<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="src" path="test"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
- <classpathentry kind="output" path="bin"/>
+ <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+ <classpathentry kind="src" path="test/main/java"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
</classpath>
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>edu.umd.cs.findbugs.plugin.eclipse.findbugsNature</nature>
</natures>
--- /dev/null
+/*
+ * jFCPlib - ARK.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Container for ARKs (address resolution keys).
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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;
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - AbstractSendFeedMessage.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Abstract base implementation for the {@code Send*Feed} commands.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public abstract class AbstractSendFeedMessage extends FcpMessage {
+
+ /**
+ * Creates a new “Send*Feed” command.
+ *
+ * @param name
+ * The name of the command
+ * @param identifier
+ * The identifier of the request
+ * @param nodeIdentifier
+ * The identifier of the peer node
+ */
+ protected AbstractSendFeedMessage(String name, String identifier, String nodeIdentifier) {
+ super(name);
+ setField("Identifier", identifier);
+ setField("NodeIdentifier", nodeIdentifier);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - AddPeer.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.net.URL;
+
+/**
+ * The “AddPeer” request adds a peer to the node.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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());
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - AllData.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.InputStream;
+
+/**
+ * The “AllData” message carries the payload of a successful {@link ClientGet}
+ * request. You will only received this message if the {@link ClientGet} request
+ * was started with a return type of {@link ReturnType#direct}. If you get this
+ * message and decide that the data is for you, call
+ * {@link #getPayloadInputStream()} to get the data. If an AllData message
+ * passes through all registered {@link FcpListener}s without the payload being
+ * consumed, the payload is discarded!
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class AllData extends BaseMessage {
+
+ /** The payload. */
+ private InputStream payloadInputStream;
+
+ /**
+ * Creates an “AllData” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ * @param payloadInputStream
+ * The payload
+ */
+ AllData(FcpMessage receivedMessage, InputStream payloadInputStream) {
+ super(receivedMessage);
+ this.payloadInputStream = payloadInputStream;
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the length of the data.
+ *
+ * @return The length of the data, or <code>-1</code> if the length could
+ * not be parsed
+ */
+ public long getDataLength() {
+ return FcpUtils.safeParseLong(getField("DataLength"));
+ }
+
+ /**
+ * Returns the startup time of the request.
+ *
+ * @return The startup time of the request (in milliseconds since Jan 1,
+ * 1970 UTC), or <code>-1</code> if the time could not be parsed
+ */
+ public long getStartupTime() {
+ return FcpUtils.safeParseLong(getField("StartupTime"));
+ }
+
+ /**
+ * Returns the completion time of the request.
+ *
+ * @return The completion time of the request (in milliseconds since Jan 1,
+ * 1970 UTC), or <code>-1</code> if the time could not be parsed
+ */
+ public long getCompletionTime() {
+ return FcpUtils.safeParseLong(getField("CompletionTime"));
+ }
+
+ /**
+ * Returns the payload input stream. You <strong>have</strong> consume the
+ * input stream before returning from the
+ * {@link FcpListener#receivedAllData(FcpConnection, AllData)} method!
+ *
+ * @return The payload
+ */
+ public InputStream getPayloadInputStream() {
+ return payloadInputStream;
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - BaseMessage.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.Map;
+
+/**
+ * A basic message abstraction that wraps a received FCP message.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class BaseMessage {
+
+ /** The received message, wrapped here. */
+ private final FcpMessage receivedMessage;
+
+ /**
+ * Creates a new base message that wraps the given message.
+ *
+ * @param receivedMessage
+ * The FCP message that was received
+ */
+ BaseMessage(FcpMessage receivedMessage) {
+ this.receivedMessage = receivedMessage;
+ }
+
+ /**
+ * Returns the name of the message.
+ *
+ * @return The name of the message
+ */
+ public String getName() {
+ return receivedMessage.getName();
+ }
+
+ /**
+ * Returns the content of the field.
+ *
+ * @param field
+ * The name of the field
+ * @return The content of the field, or <code>null</code> if there is no
+ * such field
+ */
+ protected String getField(String field) {
+ return receivedMessage.getField(field);
+ }
+
+ /**
+ * Returns all fields from the received message.
+ *
+ * @see FcpMessage#getFields()
+ * @return All fields from the message
+ */
+ protected Map<String, String> getFields() {
+ return receivedMessage.getFields();
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ClientGet.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ClientGet” request is used for download files from the Freenet node.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ClientGet extends FcpMessage {
+
+ /**
+ * Creates a new “ClientGet” request.
+ *
+ * @param uri
+ * The URI to get
+ * @param identifier
+ * The identifier of the request
+ */
+ public ClientGet(String uri, String identifier) {
+ this(uri, identifier, ReturnType.direct);
+ }
+
+ /**
+ * Creates a new “ClientGet” request.
+ *
+ * @param uri
+ * The URI to get
+ * @param identifier
+ * The identifier of the request
+ * @param returnType
+ * The return type of the request
+ */
+ public ClientGet(String uri, String identifier, ReturnType returnType) {
+ super("ClientGet");
+ setField("URI", uri);
+ setField("Identifier", identifier);
+ setField("ReturnType", String.valueOf(returnType));
+ }
+
+ /**
+ * Sets whether the local data store should be ignored when searching for a
+ * key.
+ *
+ * @param ignoreDataStore
+ * <code>true</code> to ignore the local data store,
+ * <code>false</code> to include it
+ */
+ public void setIgnoreDataStore(boolean ignoreDataStore) {
+ setField("IgnoreDS", String.valueOf(ignoreDataStore));
+ }
+
+ /**
+ * Sets whether the search for the key should be restricted to the local
+ * data store only.
+ *
+ * @param dsOnly
+ * <code>true</code> to restrict the search to the local data
+ * store, <code>false</code> to search on other nodes, too
+ */
+ public void setDataStoreOnly(boolean dsOnly) {
+ setField("DSonly", String.valueOf(dsOnly));
+ }
+
+ /**
+ * Sets the verbosity of the request.
+ *
+ * @param verbosity
+ * The verbosity of the request
+ */
+ public void setVerbosity(Verbosity verbosity) {
+ setField("Verbosity", String.valueOf(verbosity));
+ }
+
+ /**
+ * Sets the maximum size of the file to retrieve. If the file is larger than
+ * this size the request will fail!
+ *
+ * @param maxSize
+ * The maximum size of the file to retrieve
+ */
+ public void setMaxSize(long maxSize) {
+ setField("MaxSize", String.valueOf(maxSize));
+ }
+
+ /**
+ * Sets the maximum size of temporary files created by the node. If a
+ * temporary file is larger than this size the request will fail!
+ *
+ * @param maxTempSize
+ * The maximum size of temporary files
+ */
+ public void setMaxTempSize(long maxTempSize) {
+ setField("MaxTempSize", String.valueOf(maxTempSize));
+ }
+
+ /**
+ * The maximum number of retries in case a block can not be retrieved.
+ *
+ * @param maxRetries
+ * The maximum number of retries for failed blocks,
+ * <code>-1</code> to try forever
+ */
+ public void setMaxRetries(int maxRetries) {
+ setField("MaxRetries", String.valueOf(maxRetries));
+ }
+
+ /**
+ * Sets the priority of the request.
+ *
+ * @param priority
+ * The priority of the request
+ */
+ public void setPriority(Priority priority) {
+ setField("PriorityClass", String.valueOf(priority));
+ }
+
+ /**
+ * Sets the persistence of the request.
+ *
+ * @param persistence
+ * The persistence of the request
+ */
+ public void setPersistence(Persistence persistence) {
+ setField("Persistence", String.valueOf(persistence));
+ }
+
+ /**
+ * Sets the client token of the request.
+ *
+ * @param clientToken
+ * The client token of the request
+ */
+ public void setClientToken(String clientToken) {
+ setField("ClientToken", clientToken);
+ }
+
+ /**
+ * Sets whether the request should be visible on the global queue.
+ *
+ * @param global
+ * <code>true</code> to make the request visible on the global
+ * queue, <code>false</code> for client-local queue only
+ */
+ public void setGlobal(boolean global) {
+ setField("Global", String.valueOf(global));
+ }
+
+ /**
+ * Sets whether to request the “binary blob” for a key.
+ *
+ * @param binaryBlob
+ * <code>true</code> to request the binary blob,
+ * <code>false</code> to get the “real thing”
+ */
+ public void setBinaryBlob(boolean binaryBlob) {
+ setField("BinaryBlob", String.valueOf(binaryBlob));
+ }
+
+ /**
+ * Sets the allowed MIME types of the requested file. If the MIME type of
+ * the file does not match one of the given MIME types the request will
+ * fail!
+ *
+ * @param allowedMimeTypes
+ * The allowed MIME types
+ */
+ public void setAllowedMimeTypes(String... allowedMimeTypes) {
+ setField("AllowedMIMETypes", FcpUtils.encodeMultiStringField(allowedMimeTypes));
+ }
+
+ /**
+ * Sets the filename to download the file to. You should only call this
+ * method if your return type is {@link ReturnType#disk}!
+ *
+ * @param filename
+ * The filename to download the file to
+ */
+ public void setFilename(String filename) {
+ setField("Filename", filename);
+ }
+
+ /**
+ * Sets the name for the temporary file. You should only call this method if
+ * your return type is {@link ReturnType#disk}!
+ *
+ * @param tempFilename
+ * The name of the temporary file
+ */
+ public void setTempFilename(String tempFilename) {
+ setField("TempFilename", tempFilename);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ClientHello.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ClientHello” message that <i>must</i> be sent to the node first thing
+ * after calling {@link FcpConnection#connect()}.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ClientPut.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ClientPut” requests inserts a single file into freenet, either uploading
+ * it directly with this messge ({@link UploadFrom#direct}), uploading it from
+ * disk ({@link UploadFrom#disk}) or by creating a redirect to another URI (
+ * {@link UploadFrom#redirect}).
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ClientPut extends FcpMessage {
+
+ /**
+ * Creates a new “ClientPut” message that inserts a file to the given URI.
+ * The file data <em>has</em> to be supplied to this message using
+ * {@link #setPayloadInputStream(java.io.InputStream)}! Using this
+ * constructor is the same as using
+ * {@link #ClientPut(String, String, UploadFrom)} with
+ * {@link UploadFrom#direct} as third parameter.
+ *
+ * @param uri
+ * The URI to insert the file to
+ * @param identifier
+ * The identifier of the request
+ */
+ public ClientPut(String uri, String identifier) {
+ this(uri, identifier, UploadFrom.direct);
+ }
+
+ /**
+ * Creates a new “ClientPut” message that inserts a file to the given URI.
+ * Depending on <code>uploadFrom</code> the file data has to be supplied in
+ * different ways: If <code>uploadFrom</code> is {@link UploadFrom#direct},
+ * use {@link #setPayloadInputStream(java.io.InputStream)} to supply the
+ * input data. If <code>uploadFrom</code> is {@link UploadFrom#disk}, use
+ * {@link #setFilename(String)} to supply the file to upload. You have to
+ * test your direct-disk access (see {@link TestDDARequest},
+ * {@link TestDDAReply}, {@link TestDDAResponse}, {@link TestDDAComplete})
+ * before using this option! If <code>uploadFrom</code> is
+ * {@link UploadFrom#redirect}, use {@link #setTargetURI(String)} to set the
+ * target URI of the redirect.
+ *
+ * @param uri
+ * The URI to insert to
+ * @param identifier
+ * The identifier of the insert
+ * @param uploadFrom
+ * The source of the upload
+ */
+ public ClientPut(String uri, String identifier, UploadFrom uploadFrom) {
+ super("ClientPut");
+ setField("URI", uri);
+ setField("Identifier", identifier);
+ setField("UploadFrom", String.valueOf(uploadFrom));
+ }
+
+ /**
+ * The MIME type of the content.
+ *
+ * @param metadataContentType
+ * The MIME type of the content
+ */
+ public void setMetadataContentType(String metadataContentType) {
+ setField("Metadata.ContentType", metadataContentType);
+ }
+
+ /**
+ * The verbosity of the request. Depending on this parameter you will
+ * received only the bare minimum of messages for the request (i.e. “it
+ * completed”) or a whole lot more.
+ *
+ * @see Verbosity
+ * @param verbosity
+ * The verbosity of the request
+ */
+ public void setVerbosity(Verbosity verbosity) {
+ setField("Verbosity", String.valueOf(verbosity));
+ }
+
+ /**
+ * The number of retries for a request if the initial try failed.
+ *
+ * @param maxRetries
+ * The maximum number of retries after failure, or
+ * <code>-1</code> to retry forever.
+ */
+ public void setMaxRetries(int maxRetries) {
+ setField("MaxRetries", String.valueOf(maxRetries));
+ }
+
+ /**
+ * Sets the priority of the request.
+ *
+ * @param priority
+ * The priority of the request
+ */
+ public void setPriority(Priority priority) {
+ setField("PriorityClass", String.valueOf(priority));
+ }
+
+ /**
+ * Determines whether the node should really insert the data or generate the
+ * final CHK only.
+ *
+ * @param getCHKOnly
+ * <code>true</code> to generate the final CHK only,
+ * <code>false</code> to really insert the data
+ */
+ public void setGetCHKOnly(boolean getCHKOnly) {
+ setField("GetCHKOnly", String.valueOf(getCHKOnly));
+ }
+
+ /**
+ * Determines whether this request appears on the global queue.
+ *
+ * @param global
+ * <code>true</code> to put the request on the global queue,
+ * <code>false</code> for the client-local queue.
+ */
+ public void setGlobal(boolean global) {
+ setField("Global", String.valueOf(global));
+ }
+
+ /**
+ * Determines whether the node should skip compression because the file has
+ * already been compressed.
+ *
+ * @param dontCompress
+ * <code>true</code> to skip compression of the data in the node,
+ * <code>false</code> to allow compression
+ */
+ public void setDontCompress(boolean dontCompress) {
+ setField("DontCompress", String.valueOf(dontCompress));
+ }
+
+ /**
+ * Sets an optional client token. This client token is mentioned in progress
+ * and other request-related messages and can be used to identify this
+ * request.
+ *
+ * @param clientToken
+ * The client token
+ */
+ public void setClientToken(String clientToken) {
+ setField("ClientToken", clientToken);
+ }
+
+ /**
+ * Sets the persistence of this request.
+ *
+ * @param persistence
+ * The persistence of this request
+ */
+ public void setPersistence(Persistence persistence) {
+ setField("Persistence", String.valueOf(persistence));
+ }
+
+ /**
+ * Sets the target filename of the inserted file. This value is ignored for
+ * all inserts that do not have “CHK@” as a target.
+ *
+ * @param targetFilename
+ * The filename of the target
+ */
+ public void setTargetFilename(String targetFilename) {
+ setField("TargetFilename", targetFilename);
+ }
+
+ /**
+ * Determines whether to encode the complete file early in the life of the
+ * request.
+ *
+ * @param earlyEncode
+ * <code>true</code> to generate the final key long before the
+ * file is completely fetchable
+ */
+ public void setEarlyEncode(boolean earlyEncode) {
+ setField("EarlyEncode", String.valueOf(earlyEncode));
+ }
+
+ /**
+ * Sets the length of the data that will be transferred after this message
+ * if <code>uploadFrom</code> is {@link UploadFrom#direct} is used.
+ *
+ * @param dataLength
+ * The length of the data
+ */
+ public void setDataLength(long dataLength) {
+ setField("DataLength", String.valueOf(dataLength));
+ }
+
+ /**
+ * Sets the name of the file to upload the data from.
+ *
+ * @param filename
+ * The filename to upload
+ */
+ public void setFilename(String filename) {
+ setField("Filename", filename);
+ }
+
+ /**
+ * If <code>uploadFrom</code> is {@link UploadFrom#redirect}, use this
+ * method to determine that target of the redirect.
+ *
+ * @param targetURI
+ * The target URI to redirect to
+ */
+ public void setTargetURI(String targetURI) {
+ setField("TargetURI", targetURI);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ClientPutComplexDir.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.SequenceInputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import net.pterodactylus.fcp.FileEntry.DirectFileEntry;
+
+/**
+ * The “ClientPutComplexDir” lets you upload a directory with different sources
+ * for each file.
+ *
+ * @see FileEntry
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ClientPutComplexDir extends FcpMessage {
+
+ /** The index for added file entries. */
+ private int fileIndex = 0;
+
+ /** The input streams from {@link DirectFileEntry}s. */
+ private final List<InputStream> directFileInputStreams = new ArrayList<InputStream>();
+
+ /**
+ * Creates a new “ClientPutComplexDir” with the given identifier and URI.
+ *
+ * @param identifier
+ * The identifier of the request
+ * @param uri
+ * The URI to insert the directory to
+ */
+ public ClientPutComplexDir(String identifier, String uri) {
+ super("ClientPutComplexDir");
+ setField("Identifier", identifier);
+ setField("URI", uri);
+ }
+
+ /**
+ * Sets the verbosity of the request.
+ *
+ * @param verbosity
+ * The verbosity of the request
+ */
+ public void setVerbosity(Verbosity verbosity) {
+ setField("Verbosity", String.valueOf(verbosity));
+ }
+
+ /**
+ * Sets the maximum number of retries for failed blocks.
+ *
+ * @param maxRetries
+ * The maximum number of retries for failed blocks, or
+ * <code>-1</code> to retry endlessly
+ */
+ public void setMaxRetries(int maxRetries) {
+ setField("MaxRetries", String.valueOf(maxRetries));
+ }
+
+ /**
+ * Sets the priority of the request.
+ *
+ * @param priority
+ * The priority of the request
+ */
+ public void setPriority(Priority priority) {
+ setField("PriorityClass", String.valueOf(priority));
+ }
+
+ /**
+ * Sets whether to generate the final URI only.
+ *
+ * @param getCHKOnly
+ * <code>true</code> to generate the final CHK only,
+ * <code>false</code> to complete the insert
+ */
+ public void setGetCHKOnly(boolean getCHKOnly) {
+ setField("GetCHKOnly", String.valueOf(getCHKOnly));
+ }
+
+ /**
+ * Sets whether the request is on the global queue.
+ *
+ * @param global
+ * <code>true</code> to put the request on the global queue,
+ * <code>false</code> to put it on the client-local queue
+ */
+ public void setGlobal(boolean global) {
+ setField("Global", String.valueOf(global));
+ }
+
+ /**
+ * Sets whether the node should not try to compress the data.
+ *
+ * @param dontCompress
+ * <code>true</code> to skip compression of the data,
+ * <code>false</code> to try and compress the data
+ */
+ public void setDontCompress(boolean dontCompress) {
+ setField("DontCompress", String.valueOf(dontCompress));
+ }
+
+ /**
+ * Sets the client token of the request.
+ *
+ * @param clientToken
+ * The client token of the request
+ */
+ public void setClientToken(String clientToken) {
+ setField("ClientToken", clientToken);
+ }
+
+ /**
+ * Sets the persistence of the request.
+ *
+ * @param persistence
+ * The persistence of the request
+ */
+ public void setPersistence(Persistence persistence) {
+ setField("Persistence", String.valueOf(persistence));
+ }
+
+ /**
+ * Sets the target filename of the request. This is useful for inserts that
+ * go to “CHK@” only and creates a manifest with a single file.
+ *
+ * @param targetFilename
+ * The target filename
+ */
+ public void setTargetFilename(String targetFilename) {
+ setField("TargetFilename", targetFilename);
+ }
+
+ /**
+ * Sets whether to encode the complete data early to generate the
+ * {@link URIGenerated} message early.
+ *
+ * @param earlyEncode
+ * <code>true</code> to encode the complete data early,
+ * <code>false</code> otherwise
+ */
+ public void setEarlyEncode(boolean earlyEncode) {
+ setField("EarlyEncode", String.valueOf(earlyEncode));
+ }
+
+ /**
+ * Sets the default name. This is the name of the file that should be shown
+ * if no file was specified.
+ *
+ * @param defaultName
+ * The default name
+ */
+ public void setDefaultName(String defaultName) {
+ setField("DefaultName", defaultName);
+ }
+
+ /**
+ * Adds an entry for a file.
+ *
+ * @param fileEntry
+ * The file entry to add
+ */
+ public void addFileEntry(FileEntry fileEntry) {
+ Map<String, String> fields = fileEntry.getFields();
+ for (Entry<String, String> fieldEntry : fields.entrySet()) {
+ setField("Files." + fileIndex + "." + fieldEntry.getKey(), fieldEntry.getValue());
+ }
+ fileIndex++;
+ if (fileEntry instanceof FileEntry.DirectFileEntry) {
+ directFileInputStreams.add(((DirectFileEntry) fileEntry).getInputStream());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Do not call this method to add input streams! The input streams, if any,
+ * will be taken directly from the {@link FileEntry}s and the stream you set
+ * here will be overridden!
+ */
+ @Override
+ public void setPayloadInputStream(InputStream payloadInputStream) {
+ /* do nothing. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(OutputStream outputStream) throws IOException {
+ /* create payload stream. */
+ setPayloadInputStream(new SequenceInputStream(Collections.enumeration(directFileInputStreams)));
+ /* write out all the fields. */
+ super.write(outputStream);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ClientPutDiskDir.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ClientPutDiskDir” message is used to insert a complete directory from
+ * the disk to a single key.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ClientPutDiskDir extends FcpMessage {
+
+ /**
+ * Creates a new “ClientPutDiskDir” message.
+ *
+ * @param uri
+ * The URI to insert the file to
+ * @param identifier
+ * The identifier of the request
+ * @param directory
+ * The name of the directory to insert
+ */
+ public ClientPutDiskDir(String uri, String identifier, String directory) {
+ super("ClientPutDiskDir");
+ setField("URI", uri);
+ setField("Identifier", identifier);
+ setField("Filename", directory);
+ }
+
+ /**
+ * The verbosity of the request. Depending on this parameter you will
+ * received only the bare minimum of messages for the request (i.e. “it
+ * completed”) or a whole lot more.
+ *
+ * @see Verbosity
+ * @param verbosity
+ * The verbosity of the request
+ */
+ public void setVerbosity(Verbosity verbosity) {
+ setField("Verbosity", String.valueOf(verbosity));
+ }
+
+ /**
+ * The number of retries for a request if the initial try failed.
+ *
+ * @param maxRetries
+ * The maximum number of retries after failure, or
+ * <code>-1</code> to retry forever.
+ */
+ public void setMaxRetries(int maxRetries) {
+ setField("MaxRetries", String.valueOf(maxRetries));
+ }
+
+ /**
+ * Sets the priority of the request.
+ *
+ * @param priority
+ * The priority of the request
+ */
+ public void setPriority(Priority priority) {
+ setField("PriorityClass", String.valueOf(priority));
+ }
+
+ /**
+ * Determines whether the node should really insert the data or generate the
+ * final CHK only.
+ *
+ * @param getCHKOnly
+ * <code>true</code> to generate the final CHK only,
+ * <code>false</code> to really insert the data
+ */
+ public void setGetCHKOnly(boolean getCHKOnly) {
+ setField("GetCHKOnly", String.valueOf(getCHKOnly));
+ }
+
+ /**
+ * Determines whether this request appears on the global queue.
+ *
+ * @param global
+ * <code>true</code> to put the request on the global queue,
+ * <code>false</code> for the client-local queue.
+ */
+ public void setGlobal(boolean global) {
+ setField("Global", String.valueOf(global));
+ }
+
+ /**
+ * Determines whether the node should skip compression because the file has
+ * already been compressed.
+ *
+ * @param dontCompress
+ * <code>true</code> to skip compression of the data in the node,
+ * <code>false</code> to allow compression
+ */
+ public void setDontCompress(boolean dontCompress) {
+ setField("DontCompress", String.valueOf(dontCompress));
+ }
+
+ /**
+ * Sets an optional client token. This client token is mentioned in progress
+ * and other request-related messages and can be used to identify this
+ * request.
+ *
+ * @param clientToken
+ * The client token
+ */
+ public void setClientToken(String clientToken) {
+ setField("ClientToken", clientToken);
+ }
+
+ /**
+ * Sets the persistence of this request.
+ *
+ * @param persistence
+ * The persistence of this request
+ */
+ public void setPersistence(Persistence persistence) {
+ setField("Persistence", String.valueOf(persistence));
+ }
+
+ /**
+ * Sets the name of the default file. The default file is shown when the key
+ * is requested with an additional name.
+ *
+ * @param defaultName
+ * The name of the default file
+ */
+ public void setDefaultName(String defaultName) {
+ setField("DefaultName", defaultName);
+ }
+
+ /**
+ * Sets whether unreadable files allow the insert to continue.
+ *
+ * @param allowUnreadableFiles
+ * <code>true</code> to just ignore unreadable files,
+ * <code>false</code> to let the insert fail when an unreadable
+ * file is encountered
+ */
+ public void setAllowUnreadableFiles(boolean allowUnreadableFiles) {
+ setField("AllowUnreadableFiles", String.valueOf(allowUnreadableFiles));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - CloseConnectionDuplicateClientName.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “CloseConnectionDuplicateClientName” message.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ConfigData.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ConfigData” message contains various aspects of the node’s configuration.
+ *
+ * @see GetConfig
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ConfigData extends BaseMessage {
+
+ /**
+ * Creates a new “ConfigData” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ ConfigData(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the current value of the given option.
+ *
+ * @param option
+ * The name of the option
+ * @return The current value of the option
+ */
+ public String getCurrent(String option) {
+ return getField("current." + option);
+ }
+
+ /**
+ * Returns the short description of the given option.
+ *
+ * @param option
+ * The name of the option
+ * @return The short description of the option
+ */
+ public String getShortDescription(String option) {
+ return getField("shortDescription." + option);
+ }
+
+ /**
+ * Returns the long description of the given option.
+ *
+ * @param option
+ * The name of the option
+ * @return The long description of the option
+ */
+ public String getLongDescription(String option) {
+ return getField("longDescription." + option);
+ }
+
+ /**
+ * Returns the data type of the given option.
+ *
+ * @param option
+ * The name of the option
+ * @return The data type of the option
+ */
+ public String getDataType(String option) {
+ return getField("dataType." + option);
+ }
+
+ /**
+ * Returns the default value of the given option.
+ *
+ * @param option
+ * The name of the option
+ * @return The default value of the option
+ */
+ public String getDefault(String option) {
+ return getField("default." + option);
+ }
+
+ /**
+ * Returns the sort order of the given option.
+ *
+ * @param option
+ * The name of the option
+ * @return The sort order of the option, or <code>-1</code> if the sort
+ * order could not be parsed
+ */
+ public int getSortOrder(String option) {
+ return FcpUtils.safeParseInt(getField("sortOrder." + option));
+ }
+
+ /**
+ * Returns the expert flag of the given option.
+ *
+ * @param option
+ * The name of the option
+ * @return The expert flag of the option
+ */
+ public boolean getExpertFlag(String option) {
+ return Boolean.valueOf(getField("expertFlag." + option));
+ }
+
+ /**
+ * Returns the force-write flag of the given option
+ *
+ * @param option
+ * The name of the option
+ * @return The force-write flag of the given option
+ */
+ public boolean getForceWriteFlag(String option) {
+ return Boolean.valueOf(getField("forceWriteFlag." + option));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - DSAGroup.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.security.interfaces.DSAParams;
+
+/**
+ * Container for the DSA group of a peer. A DSA group consists of a base (called
+ * “g”), a prime (called “p”) and a subprime (called “q”).
+ *
+ * @see DSAParams
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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;
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - DataFound.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “DataFound” message signals the client that the data requested by a
+ * {@link ClientGet} operation has been found. This message does not include the
+ * actual data, though.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class DataFound extends BaseMessage {
+
+ /**
+ * Creates a new “DataFound” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ DataFound(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns whether the request is on the global queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> if the request is on the client-local queue
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the content type of the data.
+ *
+ * @return The content type of the data
+ */
+ public String getMetadataContentType() {
+ return getField("Metadata.ContentType");
+ }
+
+ /**
+ * Returns the length of the data.
+ *
+ * @return The length of the data
+ */
+ public long getDataLength() {
+ return FcpUtils.safeParseLong(getField("DataLength"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - EndListPeerNotes.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “EndListPeerNotes” message signals the end of a list of “PeerNote”
+ * messages.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - EndListPeers.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * This message marks the end of a list of “Peer” replies.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class EndListPeers extends BaseMessage {
+
+ /**
+ * Creates a new “EndListPeers” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The message that was received
+ */
+ EndListPeers(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - EndListPersistentRequests.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “EndListPersistentRequests” message signals the end of a list of
+ * {@link PersistentGet} and {@link PersistentPut} requests.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PluginMessage.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * An “CPPluginMessage” sends a message with custom parameters and (optional)
+ * payload to a plugin.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FCPPluginReply.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * The “FCPPluginReply” is sent by a plugin as a response to a
+ * {@link FCPPluginMessage} message.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class FCPPluginReply extends BaseMessage {
+
+ /** The payload input stream. */
+ private final InputStream payloadInputStream;
+
+ /**
+ * Creates a new “FCPPluginReply” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ * @param payloadInputStream
+ * The optional input stream for the payload
+ */
+ FCPPluginReply(FcpMessage receivedMessage, InputStream payloadInputStream) {
+ super(receivedMessage);
+ this.payloadInputStream = payloadInputStream;
+ }
+
+ /**
+ * Returns the name of the plugin.
+ *
+ * @return The name of the plugin
+ */
+ public String getPluginName() {
+ return getField("PluginName");
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the length of the optional payload.
+ *
+ * @return The length of the payload, or <code>-1</code> if there is no
+ * payload or the length could not be parsed
+ */
+ public long getDataLength() {
+ return FcpUtils.safeParseLong(getField("DataLength"));
+ }
+
+ /**
+ * Returns a reply from the plugin.
+ *
+ * @param key
+ * The name of the reply
+ * @return The value of the reply
+ */
+ public String getReply(String key) {
+ return getField("Replies." + key);
+ }
+
+ /**
+ * Returns all replies from the plugin. The plugin sends replies as normal
+ * message fields prefixed by “Replies.”. The keys of the returned map do
+ * not contain this prefix!
+ *
+ * @return All replies from the plugin
+ */
+ public Map<String, String> getReplies() {
+ Map<String, String> fields = getFields();
+ Map<String, String> replies = new HashMap<String, String>();
+ for (Entry<String, String> field : fields.entrySet()) {
+ if (field.getKey().startsWith("Replies.")) {
+ replies.put(field.getKey().substring(8), field.getValue());
+ }
+ }
+ return replies;
+ }
+
+ /**
+ * Returns the optional payload.
+ *
+ * @return The payload of the reply, or <code>null</code> if there is no
+ * payload
+ */
+ public InputStream getPayloadInputStream() {
+ return payloadInputStream;
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpAdapter.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Adapter for {@link FcpListener}.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class FcpAdapter implements FcpListener {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see FcpListener#receivedNodeData(FcpConnection, NodeData)
+ */
+ public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see FcpListener#receivedTestDDAReply(FcpConnection, TestDDAReply)
+ */
+ public void receivedTestDDAReply(FcpConnection fcpConnection, TestDDAReply testDDAReply) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedTestDDAComplete(FcpConnection fcpConnection, TestDDAComplete testDDAComplete) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedURIGenerated(FcpConnection fcpConnection, URIGenerated uriGenerated) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedAllData(FcpConnection fcpConnection, AllData allData) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedStartedCompression(FcpConnection fcpConnection, StartedCompression startedCompression) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedFinishedCompression(FcpConnection fcpConnection, FinishedCompression finishedCompression) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedUnknownPeerNoteType(FcpConnection fcpConnection, UnknownPeerNoteType unknownPeerNoteType) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedUnknownNodeIdentifier(FcpConnection fcpConnection, UnknownNodeIdentifier unknownNodeIdentifier) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedConfigData(FcpConnection fcpConnection, ConfigData configData) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPutFailed(FcpConnection fcpConnection, PutFailed putFailed) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedIdentifierCollision(FcpConnection fcpConnection, IdentifierCollision identifierCollision) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPersistentPutDir(FcpConnection fcpConnection, PersistentPutDir persistentPutDir) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedSubscribedUSKUpdate(FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPersistentRequestModified(FcpConnection fcpConnection, PersistentRequestModified persistentRequestModified) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPutSuccessful(FcpConnection fcpConnection, PutSuccessful putSuccessful) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedPutFetchable(FcpConnection fcpConnection, PutFetchable putFetchable) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedSentFeed(FcpConnection source, SentFeed sentFeed) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedBookmarkFeed(FcpConnection fcpConnection, ReceivedBookmarkFeed receivedBookmarkFeed) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage) {
+ /* empty. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
+ /* empty. */
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FpcConnection.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.Closeable;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * An FCP connection to a Freenet node.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class FcpConnection implements Closeable {
+
+ /** Logger. */
+ private static final Logger logger = Logger.getLogger(FcpConnection.class.getName());
+
+ /** The default port for FCP v2. */
+ public static final int DEFAULT_PORT = 9481;
+
+ /** Listener management. */
+ private final FcpListenerManager fcpListenerManager = new FcpListenerManager(this);
+
+ /** The address of the node. */
+ private final InetAddress address;
+
+ /** The port number of the node’s FCP port. */
+ private final int port;
+
+ /** The remote socket. */
+ private Socket remoteSocket;
+
+ /** The input stream from the node. */
+ private InputStream remoteInputStream;
+
+ /** The output stream to the node. */
+ private OutputStream remoteOutputStream;
+
+ /** The connection handler. */
+ private FcpConnectionHandler connectionHandler;
+
+ /** Incoming message statistics. */
+ private Map<String, Integer> incomingMessageStatistics = Collections.synchronizedMap(new HashMap<String, Integer>());
+
+ /**
+ * Creates a new FCP connection to the freenet node running on localhost,
+ * using the default port.
+ *
+ * @throws UnknownHostException
+ * if the hostname can not be resolved
+ */
+ public FcpConnection() throws UnknownHostException {
+ this(InetAddress.getLocalHost());
+ }
+
+ /**
+ * Creates a new FCP connection to the Freenet node running on the given
+ * host, listening on the default port.
+ *
+ * @param host
+ * The hostname of the Freenet node
+ * @throws UnknownHostException
+ * if <code>host</code> can not be resolved
+ */
+ public FcpConnection(String host) throws UnknownHostException {
+ this(host, DEFAULT_PORT);
+ }
+
+ /**
+ * Creates a new FCP connection to the Freenet node running on the given
+ * host, listening on the given port.
+ *
+ * @param host
+ * The hostname of the Freenet node
+ * @param port
+ * The port number of the node’s FCP port
+ * @throws UnknownHostException
+ * if <code>host</code> can not be resolved
+ */
+ public FcpConnection(String host, int port) throws UnknownHostException {
+ this(InetAddress.getByName(host), port);
+ }
+
+ /**
+ * Creates a new FCP connection to the Freenet node running at the given
+ * address, listening on the default port.
+ *
+ * @param address
+ * The address of the Freenet node
+ */
+ public FcpConnection(InetAddress address) {
+ this(address, DEFAULT_PORT);
+ }
+
+ /**
+ * Creates a new FCP connection to the Freenet node running at the given
+ * address, listening on the given port.
+ *
+ * @param address
+ * The address of the Freenet node
+ * @param port
+ * The port number of the node’s FCP port
+ */
+ public FcpConnection(InetAddress address, int port) {
+ this.address = address;
+ this.port = port;
+ }
+
+ //
+ // LISTENER MANAGEMENT
+ //
+
+ /**
+ * Adds the given listener to the list of listeners.
+ *
+ * @param fcpListener
+ * The listener to add
+ */
+ public void addFcpListener(FcpListener fcpListener) {
+ fcpListenerManager.addListener(fcpListener);
+ }
+
+ /**
+ * Removes the given listener from the list of listeners.
+ *
+ * @param fcpListener
+ * The listener to remove
+ */
+ public void removeFcpListener(FcpListener fcpListener) {
+ fcpListenerManager.removeListener(fcpListener);
+ }
+
+ //
+ // ACTIONS
+ //
+
+ /**
+ * Connects to the node.
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws IllegalStateException
+ * if there is already a connection to the node
+ */
+ public synchronized void connect() throws IOException, IllegalStateException {
+ if (connectionHandler != null) {
+ throw new IllegalStateException("already connected, disconnect first");
+ }
+ logger.info("connecting to " + address + ":" + port + "…");
+ remoteSocket = new Socket(address, port);
+ remoteInputStream = remoteSocket.getInputStream();
+ remoteOutputStream = remoteSocket.getOutputStream();
+ new Thread(connectionHandler = new FcpConnectionHandler(this, remoteInputStream)).start();
+ }
+
+ /**
+ * Disconnects from the node. If there is no connection to the node, this
+ * method does nothing.
+ *
+ * @deprecated Use {@link #close()} instead
+ */
+ @Deprecated
+ public synchronized void disconnect() {
+ close();
+ }
+
+ /**
+ * Closes the connection. If there is no connection to the node, this method
+ * does nothing.
+ */
+ public void close() {
+ handleDisconnect(null);
+ }
+
+ /**
+ * Sends the given FCP message.
+ *
+ * @param fcpMessage
+ * The FCP message to send
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public synchronized void sendMessage(FcpMessage fcpMessage) throws IOException {
+ logger.fine("sending message: " + fcpMessage.getName());
+ fcpMessage.write(remoteOutputStream);
+ }
+
+ //
+ // PACKAGE-PRIVATE METHODS
+ //
+
+ /**
+ * Handles the given message, notifying listeners. This message should only
+ * be called by {@link FcpConnectionHandler}.
+ *
+ * @param fcpMessage
+ * The received message
+ */
+ void handleMessage(FcpMessage fcpMessage) {
+ logger.fine("received message: " + fcpMessage.getName());
+ String messageName = fcpMessage.getName();
+ countMessage(messageName);
+ if ("SimpleProgress".equals(messageName)) {
+ fcpListenerManager.fireReceivedSimpleProgress(new SimpleProgress(fcpMessage));
+ } else if ("ProtocolError".equals(messageName)) {
+ fcpListenerManager.fireReceivedProtocolError(new ProtocolError(fcpMessage));
+ } else if ("PersistentGet".equals(messageName)) {
+ fcpListenerManager.fireReceivedPersistentGet(new PersistentGet(fcpMessage));
+ } else if ("PersistentPut".equals(messageName)) {
+ fcpListenerManager.fireReceivedPersistentPut(new PersistentPut(fcpMessage));
+ } else if ("PersistentPutDir".equals(messageName)) {
+ fcpListenerManager.fireReceivedPersistentPutDir(new PersistentPutDir(fcpMessage));
+ } else if ("URIGenerated".equals(messageName)) {
+ fcpListenerManager.fireReceivedURIGenerated(new URIGenerated(fcpMessage));
+ } else if ("EndListPersistentRequests".equals(messageName)) {
+ fcpListenerManager.fireReceivedEndListPersistentRequests(new EndListPersistentRequests(fcpMessage));
+ } else if ("Peer".equals(messageName)) {
+ fcpListenerManager.fireReceivedPeer(new Peer(fcpMessage));
+ } else if ("PeerNote".equals(messageName)) {
+ fcpListenerManager.fireReceivedPeerNote(new PeerNote(fcpMessage));
+ } else if ("StartedCompression".equals(messageName)) {
+ fcpListenerManager.fireReceivedStartedCompression(new StartedCompression(fcpMessage));
+ } else if ("FinishedCompression".equals(messageName)) {
+ fcpListenerManager.fireReceivedFinishedCompression(new FinishedCompression(fcpMessage));
+ } else if ("GetFailed".equals(messageName)) {
+ fcpListenerManager.fireReceivedGetFailed(new GetFailed(fcpMessage));
+ } else if ("PutFetchable".equals(messageName)) {
+ fcpListenerManager.fireReceivedPutFetchable(new PutFetchable(fcpMessage));
+ } else if ("PutSuccessful".equals(messageName)) {
+ fcpListenerManager.fireReceivedPutSuccessful(new PutSuccessful(fcpMessage));
+ } else if ("PutFailed".equals(messageName)) {
+ fcpListenerManager.fireReceivedPutFailed(new PutFailed(fcpMessage));
+ } else if ("DataFound".equals(messageName)) {
+ fcpListenerManager.fireReceivedDataFound(new DataFound(fcpMessage));
+ } else if ("SubscribedUSKUpdate".equals(messageName)) {
+ fcpListenerManager.fireReceivedSubscribedUSKUpdate(new SubscribedUSKUpdate(fcpMessage));
+ } else if ("IdentifierCollision".equals(messageName)) {
+ fcpListenerManager.fireReceivedIdentifierCollision(new IdentifierCollision(fcpMessage));
+ } else if ("AllData".equals(messageName)) {
+ LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength")));
+ fcpListenerManager.fireReceivedAllData(new AllData(fcpMessage, payloadInputStream));
+ try {
+ payloadInputStream.consume();
+ } catch (IOException ioe1) {
+ /* well, ignore. when the connection handler fails, all fails. */
+ }
+ } else if ("EndListPeerNotes".equals(messageName)) {
+ fcpListenerManager.fireReceivedEndListPeerNotes(new EndListPeerNotes(fcpMessage));
+ } else if ("EndListPeers".equals(messageName)) {
+ fcpListenerManager.fireReceivedEndListPeers(new EndListPeers(fcpMessage));
+ } else if ("SSKKeypair".equals(messageName)) {
+ fcpListenerManager.fireReceivedSSKKeypair(new SSKKeypair(fcpMessage));
+ } else if ("PeerRemoved".equals(messageName)) {
+ fcpListenerManager.fireReceivedPeerRemoved(new PeerRemoved(fcpMessage));
+ } else if ("PersistentRequestModified".equals(messageName)) {
+ fcpListenerManager.fireReceivedPersistentRequestModified(new PersistentRequestModified(fcpMessage));
+ } else if ("PersistentRequestRemoved".equals(messageName)) {
+ fcpListenerManager.fireReceivedPersistentRequestRemoved(new PersistentRequestRemoved(fcpMessage));
+ } else if ("UnknownPeerNoteType".equals(messageName)) {
+ fcpListenerManager.fireReceivedUnknownPeerNoteType(new UnknownPeerNoteType(fcpMessage));
+ } else if ("UnknownNodeIdentifier".equals(messageName)) {
+ fcpListenerManager.fireReceivedUnknownNodeIdentifier(new UnknownNodeIdentifier(fcpMessage));
+ } else if ("FCPPluginReply".equals(messageName)) {
+ LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength")));
+ fcpListenerManager.fireReceivedFCPPluginReply(new FCPPluginReply(fcpMessage, payloadInputStream));
+ try {
+ payloadInputStream.consume();
+ } catch (IOException ioe1) {
+ /* ignore. */
+ }
+ } else if ("PluginInfo".equals(messageName)) {
+ fcpListenerManager.fireReceivedPluginInfo(new PluginInfo(fcpMessage));
+ } else if ("NodeData".equals(messageName)) {
+ fcpListenerManager.fireReceivedNodeData(new NodeData(fcpMessage));
+ } else if ("TestDDAReply".equals(messageName)) {
+ fcpListenerManager.fireReceivedTestDDAReply(new TestDDAReply(fcpMessage));
+ } else if ("TestDDAComplete".equals(messageName)) {
+ fcpListenerManager.fireReceivedTestDDAComplete(new TestDDAComplete(fcpMessage));
+ } else if ("ConfigData".equals(messageName)) {
+ fcpListenerManager.fireReceivedConfigData(new ConfigData(fcpMessage));
+ } else if ("NodeHello".equals(messageName)) {
+ fcpListenerManager.fireReceivedNodeHello(new NodeHello(fcpMessage));
+ } else if ("CloseConnectionDuplicateClientName".equals(messageName)) {
+ fcpListenerManager.fireReceivedCloseConnectionDuplicateClientName(new CloseConnectionDuplicateClientName(fcpMessage));
+ } else if ("SentFeed".equals(messageName)) {
+ fcpListenerManager.fireSentFeed(new SentFeed(fcpMessage));
+ } else if ("ReceivedBookmarkFeed".equals(messageName)) {
+ fcpListenerManager.fireReceivedBookmarkFeed(new ReceivedBookmarkFeed(fcpMessage));
+ } else {
+ fcpListenerManager.fireMessageReceived(fcpMessage);
+ }
+ }
+
+ /**
+ * Handles a disconnect from the node.
+ *
+ * @param throwable
+ * The exception that caused the disconnect, or <code>null</code>
+ * if there was no exception
+ */
+ synchronized void handleDisconnect(Throwable throwable) {
+ FcpUtils.close(remoteInputStream);
+ FcpUtils.close(remoteOutputStream);
+ FcpUtils.close(remoteSocket);
+ if (connectionHandler != null) {
+ connectionHandler.stop();
+ connectionHandler = null;
+ fcpListenerManager.fireConnectionClosed(throwable);
+ }
+ }
+
+ //
+ // PRIVATE METHODS
+ //
+
+ /**
+ * Incremets the counter in {@link #incomingMessageStatistics} by
+ * <cod>1</code> for the given message name.
+ *
+ * @param name
+ * The name of the message to count
+ */
+ private void countMessage(String name) {
+ int oldValue = 0;
+ if (incomingMessageStatistics.containsKey(name)) {
+ oldValue = incomingMessageStatistics.get(name);
+ }
+ incomingMessageStatistics.put(name, oldValue + 1);
+ logger.finest("count for " + name + ": " + (oldValue + 1));
+ }
+
+ /**
+ * Returns a limited input stream from the node’s input stream.
+ *
+ * @param dataLength
+ * The length of the stream
+ * @return The limited input stream
+ */
+ private synchronized LimitedInputStream getInputStream(long dataLength) {
+ if (dataLength <= 0) {
+ return new LimitedInputStream(null, 0);
+ }
+ return new LimitedInputStream(remoteInputStream, dataLength);
+ }
+
+ /**
+ * A wrapper around an {@link InputStream} that only supplies a limit number
+ * of bytes from the underlying input stream.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ private static class LimitedInputStream extends FilterInputStream {
+
+ /** The remaining number of bytes that can be read. */
+ private long remaining;
+
+ /**
+ * Creates a new LimitedInputStream that supplies at most
+ * <code>length</code> bytes from the given input stream.
+ *
+ * @param inputStream
+ * The input stream
+ * @param length
+ * The number of bytes to read
+ */
+ public LimitedInputStream(InputStream inputStream, long length) {
+ super(inputStream);
+ remaining = length;
+ }
+
+ /**
+ * @see java.io.FilterInputStream#available()
+ */
+ @Override
+ public synchronized int available() throws IOException {
+ if (remaining == 0) {
+ return 0;
+ }
+ return (int) Math.min(super.available(), Math.min(Integer.MAX_VALUE, remaining));
+ }
+
+ /**
+ * @see java.io.FilterInputStream#read()
+ */
+ @Override
+ public synchronized int read() throws IOException {
+ int read = -1;
+ if (remaining > 0) {
+ read = super.read();
+ remaining--;
+ }
+ return read;
+ }
+
+ /**
+ * @see java.io.FilterInputStream#read(byte[], int, int)
+ */
+ @Override
+ public synchronized int read(byte[] b, int off, int len) throws IOException {
+ if (remaining == 0) {
+ return -1;
+ }
+ int toCopy = (int) Math.min(len, Math.min(remaining, Integer.MAX_VALUE));
+ int read = super.read(b, off, toCopy);
+ remaining -= read;
+ return read;
+ }
+
+ /**
+ * @see java.io.FilterInputStream#skip(long)
+ */
+ @Override
+ public synchronized long skip(long n) throws IOException {
+ if ((n < 0) || (remaining == 0)) {
+ return 0;
+ }
+ long skipped = super.skip(Math.min(n, remaining));
+ remaining -= skipped;
+ return skipped;
+ }
+
+ /**
+ * {@inheritDoc} This method does nothing, as {@link #mark(int)} and
+ * {@link #reset()} are not supported.
+ *
+ * @see java.io.FilterInputStream#mark(int)
+ */
+ @Override
+ public void mark(int readlimit) {
+ /* do nothing. */
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.io.FilterInputStream#markSupported()
+ * @return <code>false</code>
+ */
+ @Override
+ public boolean markSupported() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc} This method does nothing, as {@link #mark(int)} and
+ * {@link #reset()} are not supported.
+ *
+ * @see java.io.FilterInputStream#reset()
+ */
+ @Override
+ public void reset() throws IOException {
+ /* do nothing. */
+ }
+
+ /**
+ * Consumes the input stream, i.e. read all bytes until the limit is
+ * reached.
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public synchronized void consume() throws IOException {
+ while (remaining > 0) {
+ skip(remaining);
+ }
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpConnectionHandler.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * Handles an FCP connection to a node.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+class FcpConnectionHandler implements Runnable {
+
+ /** The underlying connection. */
+ private final FcpConnection fcpConnection;
+
+ /** The input stream from the node. */
+ private final InputStream remoteInputStream;
+
+ /** Whether to stop the connection handler. */
+ private boolean shouldStop;
+
+ /** Whether the next read line feed should be ignored. */
+ private boolean ignoreNextLinefeed;
+
+ /**
+ * Creates a new connection handler that operates on the given connection
+ * and input stream.
+ *
+ * @param fcpConnection
+ * The underlying FCP connection
+ * @param remoteInputStream
+ * The input stream from the node
+ */
+ public FcpConnectionHandler(FcpConnection fcpConnection, InputStream remoteInputStream) {
+ this.fcpConnection = fcpConnection;
+ this.remoteInputStream = remoteInputStream;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void run() {
+ FcpMessage fcpMessage = null;
+ Throwable throwable = null;
+ while (true) {
+ synchronized (this) {
+ if (shouldStop) {
+ break;
+ }
+ }
+ try {
+ String line = readLine();
+ System.out.println("read line: " + line);
+ if (line == null) {
+ break;
+ }
+ if (line.length() == 0) {
+ continue;
+ }
+ line = line.trim();
+ if (fcpMessage == null) {
+ fcpMessage = new FcpMessage(line);
+ continue;
+ }
+ if ("EndMessage".equalsIgnoreCase(line) || "Data".equalsIgnoreCase(line)) {
+ fcpConnection.handleMessage(fcpMessage);
+ fcpMessage = null;
+ }
+ int equalSign = line.indexOf('=');
+ if (equalSign == -1) {
+ /* something's fishy! */
+ continue;
+ }
+ String field = line.substring(0, equalSign);
+ String value = line.substring(equalSign + 1);
+ assert fcpMessage != null: "fcp message is null";
+ fcpMessage.setField(field, value);
+ } catch (IOException ioe1) {
+ throwable = ioe1;
+ break;
+ }
+ }
+ fcpConnection.handleDisconnect(throwable);
+ }
+
+ /**
+ * Stops the connection handler.
+ */
+ public void stop() {
+ synchronized (this) {
+ shouldStop = true;
+ }
+ }
+
+ //
+ // PRIVATE METHODS
+ //
+
+ /**
+ * Reads bytes from {@link #remoteInputStream} until ‘\r’ or ‘\n’ are
+ * encountered and decodes the read bytes using UTF-8.
+ *
+ * @return The decoded line
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ private String readLine() throws IOException {
+ byte[] readBytes = new byte[512];
+ int readIndex = 0;
+ while (true) {
+ int nextByte = remoteInputStream.read();
+ if (nextByte == -1) {
+ if (readIndex == 0) {
+ return null;
+ }
+ break;
+ }
+ if (nextByte == 10) {
+ if (!ignoreNextLinefeed) {
+ break;
+ }
+ }
+ ignoreNextLinefeed = false;
+ if (nextByte == 13) {
+ ignoreNextLinefeed = true;
+ break;
+ }
+ if (readIndex == readBytes.length) {
+ /* recopy & enlarge array */
+ byte[] newReadBytes = new byte[readBytes.length * 2];
+ System.arraycopy(readBytes, 0, newReadBytes, 0, readBytes.length);
+ readBytes = newReadBytes;
+ }
+ readBytes[readIndex++] = (byte) nextByte;
+ }
+ ByteBuffer byteBuffer = ByteBuffer.wrap(readBytes, 0, readIndex);
+ return Charset.forName("UTF-8").decode(byteBuffer).toString();
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpKeyPair.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Container for an SSK keypair.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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;
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FpcListener.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.EventListener;
+
+/**
+ * Interface for objects that want to be notified on certain FCP events.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public interface FcpListener extends EventListener {
+
+ /**
+ * Notifies a listener that a “NodeHello” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param nodeHello
+ * The “NodeHello” message
+ */
+ public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello);
+
+ /**
+ * Notifies a listener that a “CloseConnectionDuplicateClientName” message
+ * was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param closeConnectionDuplicateClientName
+ * The “CloseConnectionDuplicateClientName” message
+ */
+ public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName);
+
+ /**
+ * Notifies a listener that a “SSKKeypair” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received themessage
+ * @param sskKeypair
+ * The “SSKKeypair” message
+ */
+ public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair);
+
+ /**
+ * Notifies a listener that a “Peer” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param peer
+ * The “Peer” message
+ */
+ public void receivedPeer(FcpConnection fcpConnection, Peer peer);
+
+ /**
+ * Notifies a listener that an “EndListPeers” message was received.
+ *
+ * @param fcpConnection
+ * The connection that recevied the message
+ * @param endListPeers
+ * The “EndListPeers” message
+ */
+ public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers);
+
+ /**
+ * Notifies a listener that a “PeerNote” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param peerNote
+ * The “PeerNote” message
+ */
+ public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote);
+
+ /**
+ * Notifies a listener that an “EndListPeerNotes” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param endListPeerNotes
+ * The “EndListPeerNotes” message
+ */
+ public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes);
+
+ /**
+ * Notifies a listener that a “PeerRemoved” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param peerRemoved
+ * The “PeerRemoved” message
+ */
+ public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved);
+
+ /**
+ * Notifies a listener that a “NodeData” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param nodeData
+ * The “NodeData” message
+ */
+ public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData);
+
+ /**
+ * Notifies a listener that a “TestDDAReply” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param testDDAReply
+ * The “TestDDAReply” message
+ */
+ public void receivedTestDDAReply(FcpConnection fcpConnection, TestDDAReply testDDAReply);
+
+ /**
+ * Notifies a listener that a “TestDDAComplete” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param testDDAComplete
+ * The “TestDDAComplete” message
+ */
+ public void receivedTestDDAComplete(FcpConnection fcpConnection, TestDDAComplete testDDAComplete);
+
+ /**
+ * Notifies a listener that a “PersistentGet” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param persistentGet
+ * The “PersistentGet” message
+ */
+ public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet);
+
+ /**
+ * Notifies a listener that a “PersistentPut” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param persistentPut
+ * The “PersistentPut” message
+ */
+ public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut);
+
+ /**
+ * Notifies a listener that a “EndListPersistentRequests” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param endListPersistentRequests
+ * The “EndListPersistentRequests” message
+ */
+ public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests);
+
+ /**
+ * Notifies a listener that a “URIGenerated” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param uriGenerated
+ * The “URIGenerated” message
+ */
+ public void receivedURIGenerated(FcpConnection fcpConnection, URIGenerated uriGenerated);
+
+ /**
+ * Notifies a listener that a “DataFound” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param dataFound
+ * The “DataFound” message
+ */
+ public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound);
+
+ /**
+ * Notifies a listener that an “AllData” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param allData
+ * The “AllData” message
+ */
+ public void receivedAllData(FcpConnection fcpConnection, AllData allData);
+
+ /**
+ * Notifies a listener that a “SimpleProgress” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param simpleProgress
+ * The “SimpleProgress” message
+ */
+ public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress);
+
+ /**
+ * Notifies a listener that a “StartedCompression” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param startedCompression
+ * The “StartedCompression” message
+ */
+ public void receivedStartedCompression(FcpConnection fcpConnection, StartedCompression startedCompression);
+
+ /**
+ * Notifies a listener that a “FinishedCompression” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param finishedCompression
+ * The “FinishedCompression” message
+ */
+ public void receivedFinishedCompression(FcpConnection fcpConnection, FinishedCompression finishedCompression);
+
+ /**
+ * Notifies a listener that an “UnknownPeerNoteType” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param unknownPeerNoteType
+ * The “UnknownPeerNoteType” message
+ */
+ public void receivedUnknownPeerNoteType(FcpConnection fcpConnection, UnknownPeerNoteType unknownPeerNoteType);
+
+ /**
+ * Notifies a listener that a “UnknownNodeIdentifier” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param unknownNodeIdentifier
+ * The “UnknownNodeIdentifier” message
+ */
+ public void receivedUnknownNodeIdentifier(FcpConnection fcpConnection, UnknownNodeIdentifier unknownNodeIdentifier);
+
+ /**
+ * Notifies a listener that a “ConfigData” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param configData
+ * The “ConfigData” message
+ */
+ public void receivedConfigData(FcpConnection fcpConnection, ConfigData configData);
+
+ /**
+ * Notifies a listener that a “GetFailed” message was recevied.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param getFailed
+ * The “GetFailed” message
+ */
+ public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed);
+
+ /**
+ * Notifies a listener that a “PutFailed” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param putFailed
+ * The “PutFailed” message
+ */
+ public void receivedPutFailed(FcpConnection fcpConnection, PutFailed putFailed);
+
+ /**
+ * Notifies a listener that an “IdentifierCollision” message was receied.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param identifierCollision
+ * The “IdentifierCollision” message
+ */
+ public void receivedIdentifierCollision(FcpConnection fcpConnection, IdentifierCollision identifierCollision);
+
+ /**
+ * Notifies a listener that a “PersistentPutDir” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param persistentPutDir
+ * The “PersistentPutDir” message
+ */
+ public void receivedPersistentPutDir(FcpConnection fcpConnection, PersistentPutDir persistentPutDir);
+
+ /**
+ * Notifies a listener that a “PersistentRequestRemoved” message was
+ * received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param persistentRequestRemoved
+ * The “PersistentRequestRemoved” message
+ */
+ public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved);
+
+ /**
+ * Notifies a listener that a “SubscribedUSKUpdate” message was received.
+ *
+ * @param fcpConnection
+ * The connection that recevied the message
+ * @param subscribedUSKUpdate
+ * The “SubscribedUSKUpdate” message
+ */
+ public void receivedSubscribedUSKUpdate(FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate);
+
+ /**
+ * Notifies a listener that a “PluginInfo” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param pluginInfo
+ * The “PluginInfo” message
+ */
+ public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo);
+
+ /**
+ * Notifies a listener that an “FCPPluginReply“ message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param fcpPluginReply
+ * The “FCPPluginReply” message
+ */
+ public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply);
+
+ /**
+ * Notifies a listener that a “PersistentRequestModified” message was
+ * received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param persistentRequestModified
+ * The “PersistentRequestModified” message
+ */
+ public void receivedPersistentRequestModified(FcpConnection fcpConnection, PersistentRequestModified persistentRequestModified);
+
+ /**
+ * Notifies a listener that a “PutSuccessful” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param putSuccessful
+ * The “PutSuccessful” message
+ */
+ public void receivedPutSuccessful(FcpConnection fcpConnection, PutSuccessful putSuccessful);
+
+ /**
+ * Notifies a listener that a “PutFetchable” message was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param putFetchable
+ * The “PutFetchable” message
+ */
+ public void receivedPutFetchable(FcpConnection fcpConnection, PutFetchable putFetchable);
+
+ /**
+ * Notifies a listener that a feed was sent to a peer.
+ *
+ * @param source
+ * The connection that received the message
+ * @param sentFeed
+ * The “SentFeed” message
+ */
+ public void receivedSentFeed(FcpConnection source, SentFeed sentFeed);
+
+ /**
+ * Notifies a listener that a bookmark was updated.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param receivedBookmarkFeed
+ * The “ReceivedBookmarkFeed” message
+ */
+ public void receivedBookmarkFeed(FcpConnection fcpConnection, ReceivedBookmarkFeed receivedBookmarkFeed);
+
+ /**
+ * Notifies a listener that a “ProtocolError” was received.
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param protocolError
+ * The “ProtocolError” message
+ */
+ public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError);
+
+ /**
+ * Notifies a listener that a message has been received. This method is only
+ * called if {@link FcpConnection#handleMessage(FcpMessage)} does not
+ * recognize the message. Should that ever happen, please file a bug report!
+ *
+ * @param fcpConnection
+ * The connection that received the message
+ * @param fcpMessage
+ * The message that was received
+ */
+ public void receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage);
+
+ /**
+ * Notifies a listener that a connection was closed. A closed connection can
+ * be reestablished by calling {@link FcpConnection#connect()} on the same
+ * object again.
+ *
+ * @param fcpConnection
+ * The connection that was closed.
+ * @param throwable
+ * The exception that caused the disconnect, or <code>null</code>
+ * if there was no exception
+ */
+ public void connectionClosed(FcpConnection fcpConnection, Throwable throwable);
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpListenerManager.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import net.pterodactylus.util.event.AbstractListenerManager;
+
+/**
+ * Manages FCP listeners and event firing.
+ *
+ * @author David ‘Bombe’ Roden <bombe@pterodactylus.net>
+ */
+public class FcpListenerManager extends AbstractListenerManager<FcpConnection, FcpListener> {
+
+ /**
+ * Creates a new listener manager.
+ *
+ * @param fcpConnection
+ * The source FCP connection
+ */
+ public FcpListenerManager(FcpConnection fcpConnection) {
+ super(fcpConnection);
+ }
+
+ /**
+ * Notifies listeners that a “NodeHello” message was received.
+ *
+ * @see FcpListener#receivedNodeHello(FcpConnection, NodeHello)
+ * @param nodeHello
+ * The “NodeHello” message
+ */
+ public void fireReceivedNodeHello(NodeHello nodeHello) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedNodeHello(getSource(), nodeHello);
+ }
+ }
+
+ /**
+ * Notifies listeners that a “CloseConnectionDuplicateClientName” message
+ * was received.
+ *
+ * @see FcpListener#receivedCloseConnectionDuplicateClientName(FcpConnection,
+ * CloseConnectionDuplicateClientName)
+ * @param closeConnectionDuplicateClientName
+ * The “CloseConnectionDuplicateClientName” message
+ */
+ public void fireReceivedCloseConnectionDuplicateClientName(CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedCloseConnectionDuplicateClientName(getSource(), closeConnectionDuplicateClientName);
+ }
+ }
+
+ /**
+ * Notifies listeners that a “SSKKeypair” message was received.
+ *
+ * @see FcpListener#receivedSSKKeypair(FcpConnection, SSKKeypair)
+ * @param sskKeypair
+ * The “SSKKeypair” message
+ */
+ public void fireReceivedSSKKeypair(SSKKeypair sskKeypair) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedSSKKeypair(getSource(), sskKeypair);
+ }
+ }
+
+ /**
+ * Notifies listeners that a “Peer” message was received.
+ *
+ * @see FcpListener#receivedPeer(FcpConnection, Peer)
+ * @param peer
+ * The “Peer” message
+ */
+ public void fireReceivedPeer(Peer peer) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPeer(getSource(), peer);
+ }
+ }
+
+ /**
+ * Notifies all listeners that an “EndListPeers” message was received.
+ *
+ * @see FcpListener#receivedEndListPeers(FcpConnection, EndListPeers)
+ * @param endListPeers
+ * The “EndListPeers” message
+ */
+ public void fireReceivedEndListPeers(EndListPeers endListPeers) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedEndListPeers(getSource(), endListPeers);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “PeerNote” message was received.
+ *
+ * @see FcpListener#receivedPeerNote(FcpConnection, PeerNote)
+ * @param peerNote
+ */
+ public void fireReceivedPeerNote(PeerNote peerNote) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPeerNote(getSource(), peerNote);
+ }
+ }
+
+ /**
+ * Notifies all listeners that an “EndListPeerNotes” message was received.
+ *
+ * @see FcpListener#receivedEndListPeerNotes(FcpConnection,
+ * EndListPeerNotes)
+ * @param endListPeerNotes
+ * The “EndListPeerNotes” message
+ */
+ public void fireReceivedEndListPeerNotes(EndListPeerNotes endListPeerNotes) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedEndListPeerNotes(getSource(), endListPeerNotes);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “PeerRemoved” message was received.
+ *
+ * @see FcpListener#receivedPeerRemoved(FcpConnection, PeerRemoved)
+ * @param peerRemoved
+ * The “PeerRemoved” message
+ */
+ public void fireReceivedPeerRemoved(PeerRemoved peerRemoved) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPeerRemoved(getSource(), peerRemoved);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “NodeData” message was received.
+ *
+ * @see FcpListener#receivedNodeData(FcpConnection, NodeData)
+ * @param nodeData
+ * The “NodeData” message
+ */
+ public void fireReceivedNodeData(NodeData nodeData) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedNodeData(getSource(), nodeData);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “TestDDAReply” message was received.
+ *
+ * @see FcpListener#receivedTestDDAReply(FcpConnection, TestDDAReply)
+ * @param testDDAReply
+ * The “TestDDAReply” message
+ */
+ public void fireReceivedTestDDAReply(TestDDAReply testDDAReply) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedTestDDAReply(getSource(), testDDAReply);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “TestDDAComplete” message was received.
+ *
+ * @see FcpListener#receivedTestDDAComplete(FcpConnection, TestDDAComplete)
+ * @param testDDAComplete
+ * The “TestDDAComplete” message
+ */
+ public void fireReceivedTestDDAComplete(TestDDAComplete testDDAComplete) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedTestDDAComplete(getSource(), testDDAComplete);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “PersistentGet” message was received.
+ *
+ * @see FcpListener#receivedPersistentGet(FcpConnection, PersistentGet)
+ * @param persistentGet
+ * The “PersistentGet” message
+ */
+ public void fireReceivedPersistentGet(PersistentGet persistentGet) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPersistentGet(getSource(), persistentGet);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “PersistentPut” message was received.
+ *
+ * @see FcpListener#receivedPersistentPut(FcpConnection, PersistentPut)
+ * @param persistentPut
+ * The “PersistentPut” message
+ */
+ public void fireReceivedPersistentPut(PersistentPut persistentPut) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPersistentPut(getSource(), persistentPut);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “EndListPersistentRequests” message was
+ * received.
+ *
+ * @see FcpListener#receivedEndListPersistentRequests(FcpConnection,
+ * EndListPersistentRequests)
+ * @param endListPersistentRequests
+ * The “EndListPersistentRequests” message
+ */
+ public void fireReceivedEndListPersistentRequests(EndListPersistentRequests endListPersistentRequests) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedEndListPersistentRequests(getSource(), endListPersistentRequests);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “URIGenerated” message was received.
+ *
+ * @see FcpListener#receivedURIGenerated(FcpConnection, URIGenerated)
+ * @param uriGenerated
+ * The “URIGenerated” message
+ */
+ public void fireReceivedURIGenerated(URIGenerated uriGenerated) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedURIGenerated(getSource(), uriGenerated);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “DataFound” message was received.
+ *
+ * @see FcpListener#receivedDataFound(FcpConnection, DataFound)
+ * @param dataFound
+ * The “DataFound” message
+ */
+ public void fireReceivedDataFound(DataFound dataFound) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedDataFound(getSource(), dataFound);
+ }
+ }
+
+ /**
+ * Notifies all listeners that an “AllData” message was received.
+ *
+ * @see FcpListener#receivedAllData(FcpConnection, AllData)
+ * @param allData
+ * The “AllData” message
+ */
+ public void fireReceivedAllData(AllData allData) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedAllData(getSource(), allData);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “SimpleProgress” message was received.
+ *
+ * @see FcpListener#receivedSimpleProgress(FcpConnection, SimpleProgress)
+ * @param simpleProgress
+ * The “SimpleProgress” message
+ */
+ public void fireReceivedSimpleProgress(SimpleProgress simpleProgress) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedSimpleProgress(getSource(), simpleProgress);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “StartedCompression” message was received.
+ *
+ * @see FcpListener#receivedStartedCompression(FcpConnection,
+ * StartedCompression)
+ * @param startedCompression
+ * The “StartedCompression” message
+ */
+ public void fireReceivedStartedCompression(StartedCompression startedCompression) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedStartedCompression(getSource(), startedCompression);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “FinishedCompression” message was received.
+ *
+ * @see FcpListener#receivedFinishedCompression(FcpConnection,
+ * FinishedCompression)
+ * @param finishedCompression
+ * The “FinishedCompression” message
+ */
+ public void fireReceivedFinishedCompression(FinishedCompression finishedCompression) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedFinishedCompression(getSource(), finishedCompression);
+ }
+ }
+
+ /**
+ * Notifies all listeners that an “UnknownPeerNoteType” message was
+ * received.
+ *
+ * @see FcpListener#receivedUnknownPeerNoteType(FcpConnection,
+ * UnknownPeerNoteType)
+ * @param unknownPeerNoteType
+ * The “UnknownPeerNoteType” message
+ */
+ public void fireReceivedUnknownPeerNoteType(UnknownPeerNoteType unknownPeerNoteType) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedUnknownPeerNoteType(getSource(), unknownPeerNoteType);
+ }
+ }
+
+ /**
+ * Notifies all listeners that an “UnknownNodeIdentifier” message was
+ * received.
+ *
+ * @see FcpListener#receivedUnknownNodeIdentifier(FcpConnection,
+ * UnknownNodeIdentifier)
+ * @param unknownNodeIdentifier
+ * The “UnknownNodeIdentifier” message
+ */
+ public void fireReceivedUnknownNodeIdentifier(UnknownNodeIdentifier unknownNodeIdentifier) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedUnknownNodeIdentifier(getSource(), unknownNodeIdentifier);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “ConfigData” message was received.
+ *
+ * @see FcpListener#receivedConfigData(FcpConnection, ConfigData)
+ * @param configData
+ * The “ConfigData” message
+ */
+ public void fireReceivedConfigData(ConfigData configData) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedConfigData(getSource(), configData);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “GetFailed” message was received.
+ *
+ * @see FcpListener#receivedGetFailed(FcpConnection, GetFailed)
+ * @param getFailed
+ * The “GetFailed” message
+ */
+ public void fireReceivedGetFailed(GetFailed getFailed) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedGetFailed(getSource(), getFailed);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “PutFailed” message was received.
+ *
+ * @see FcpListener#receivedPutFailed(FcpConnection, PutFailed)
+ * @param putFailed
+ * The “PutFailed” message
+ */
+ public void fireReceivedPutFailed(PutFailed putFailed) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPutFailed(getSource(), putFailed);
+ }
+ }
+
+ /**
+ * Notifies all listeners that an “IdentifierCollision” message was
+ * received.
+ *
+ * @see FcpListener#receivedIdentifierCollision(FcpConnection,
+ * IdentifierCollision)
+ * @param identifierCollision
+ * The “IdentifierCollision” message
+ */
+ public void fireReceivedIdentifierCollision(IdentifierCollision identifierCollision) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedIdentifierCollision(getSource(), identifierCollision);
+ }
+ }
+
+ /**
+ * Notifies all listeners that an “PersistentPutDir” message was received.
+ *
+ * @see FcpListener#receivedPersistentPutDir(FcpConnection,
+ * PersistentPutDir)
+ * @param persistentPutDir
+ * The “PersistentPutDir” message
+ */
+ public void fireReceivedPersistentPutDir(PersistentPutDir persistentPutDir) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPersistentPutDir(getSource(), persistentPutDir);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “PersistentRequestRemoved” message was
+ * received.
+ *
+ * @see FcpListener#receivedPersistentRequestRemoved(FcpConnection,
+ * PersistentRequestRemoved)
+ * @param persistentRequestRemoved
+ * The “PersistentRequestRemoved” message
+ */
+ public void fireReceivedPersistentRequestRemoved(PersistentRequestRemoved persistentRequestRemoved) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPersistentRequestRemoved(getSource(), persistentRequestRemoved);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “SubscribedUSKUpdate” message was received.
+ *
+ * @see FcpListener#receivedSubscribedUSKUpdate(FcpConnection,
+ * SubscribedUSKUpdate)
+ * @param subscribedUSKUpdate
+ * The “SubscribedUSKUpdate” message
+ */
+ public void fireReceivedSubscribedUSKUpdate(SubscribedUSKUpdate subscribedUSKUpdate) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedSubscribedUSKUpdate(getSource(), subscribedUSKUpdate);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “PluginInfo” message was received.
+ *
+ * @see FcpListener#receivedPluginInfo(FcpConnection, PluginInfo)
+ * @param pluginInfo
+ * The “PluginInfo” message
+ */
+ public void fireReceivedPluginInfo(PluginInfo pluginInfo) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPluginInfo(getSource(), pluginInfo);
+ }
+ }
+
+ /**
+ * Notifies all listeners that an “FCPPluginReply” message was received.
+ *
+ * @see FcpListener#receivedFCPPluginReply(FcpConnection, FCPPluginReply)
+ * @param fcpPluginReply
+ * The “FCPPluginReply” message
+ */
+ public void fireReceivedFCPPluginReply(FCPPluginReply fcpPluginReply) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedFCPPluginReply(getSource(), fcpPluginReply);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “PersistentRequestModified” message was
+ * received.
+ *
+ * @see FcpListener#receivedPersistentRequestModified(FcpConnection,
+ * PersistentRequestModified)
+ * @param persistentRequestModified
+ * The “PersistentRequestModified” message
+ */
+ public void fireReceivedPersistentRequestModified(PersistentRequestModified persistentRequestModified) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPersistentRequestModified(getSource(), persistentRequestModified);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “PutSuccessful” message was received.
+ *
+ * @see FcpListener#receivedPutSuccessful(FcpConnection, PutSuccessful)
+ * @param putSuccessful
+ * The “PutSuccessful” message
+ */
+ public void fireReceivedPutSuccessful(PutSuccessful putSuccessful) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPutSuccessful(getSource(), putSuccessful);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “PutFetchable” message was received.
+ *
+ * @see FcpListener#receivedPutFetchable(FcpConnection, PutFetchable)
+ * @param putFetchable
+ * The “PutFetchable” message
+ */
+ public void fireReceivedPutFetchable(PutFetchable putFetchable) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedPutFetchable(getSource(), putFetchable);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “ProtocolError” message was received.
+ *
+ * @see FcpListener#receivedProtocolError(FcpConnection, ProtocolError)
+ * @param protocolError
+ * The “ProtocolError” message
+ */
+ public void fireReceivedProtocolError(ProtocolError protocolError) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedProtocolError(getSource(), protocolError);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “SentFeed” message was received.
+ *
+ * @see FcpListener#receivedSentFeed(FcpConnection, SentFeed)
+ * @param sentFeed
+ * The “SentFeed” message.
+ */
+ public void fireSentFeed(SentFeed sentFeed) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedSentFeed(getSource(), sentFeed);
+ }
+ }
+
+ /**
+ * Notifies all listeners that a “ReceivedBookmarkFeed” message was
+ * received.
+ *
+ * @see FcpListener#receivedBookmarkFeed(FcpConnection,
+ * ReceivedBookmarkFeed)
+ * @param receivedBookmarkFeed
+ * The “ReceivedBookmarkFeed” message
+ */
+ public void fireReceivedBookmarkFeed(ReceivedBookmarkFeed receivedBookmarkFeed) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedBookmarkFeed(getSource(), receivedBookmarkFeed);
+ }
+ }
+
+ /**
+ * Notifies all registered listeners that a message has been received.
+ *
+ * @see FcpListener#receivedMessage(FcpConnection, FcpMessage)
+ * @param fcpMessage
+ * The message that was received
+ */
+ public void fireMessageReceived(FcpMessage fcpMessage) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.receivedMessage(getSource(), fcpMessage);
+ }
+ }
+
+ /**
+ * Notifies all listeners that the connection to the node was closed.
+ *
+ * @param throwable
+ * The exception that caused the disconnect, or <code>null</code>
+ * if there was no exception
+ * @see FcpListener#connectionClosed(FcpConnection, Throwable)
+ */
+ public void fireConnectionClosed(Throwable throwable) {
+ for (FcpListener fcpListener : getListeners()) {
+ fcpListener.connectionClosed(getSource(), throwable);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpMessage.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * An FCP message. FCP messages consist of a name, an arbitrary amount of
+ * “fields” (i.e. key-value pairs), a message end marker, and optional payload
+ * data that follows the marker.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class FcpMessage implements Iterable<String> {
+
+ /** Constant for the linefeed. */
+ private static final String LINEFEED = "\r\n";
+
+ /** The name of the message. */
+ private final String name;
+
+ /** The fields of the message. */
+ private final Map<String, String> fields = new HashMap<String, String>();
+
+ /** The optional payload input stream. */
+ private InputStream payloadInputStream;
+
+ /**
+ * Creates a new FCP message with the given name.
+ *
+ * @param name
+ * The name of the FCP message
+ */
+ public FcpMessage(String name) {
+ this(name, null);
+ }
+
+ /**
+ * Creates a new FCP message with the given name and the given payload input
+ * stream. The payload input stream is not read until the message is sent to
+ * the node using {@link FcpConnection#sendMessage(FcpMessage)}.
+ *
+ * @param name
+ * The name of the message
+ * @param payloadInputStream
+ * The payload of the message
+ */
+ public FcpMessage(String name, InputStream payloadInputStream) {
+ this.name = name;
+ this.payloadInputStream = payloadInputStream;
+ }
+
+ /**
+ * Returns the name of the message.
+ *
+ * @return The name of the message
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Checks whether this message has a field with the given name.
+ *
+ * @param field
+ * The name of the field to check for
+ * @return <code>true</code> if the message has a field with the given name,
+ * <code>false</code> otherwise
+ */
+ public boolean hasField(String field) {
+ return fields.containsKey(field);
+ }
+
+ /**
+ * Sets the field with the given name to the given value. If the field
+ * already exists in this message it is overwritten.
+ *
+ * @param field
+ * The name of the field
+ * @param value
+ * The value of the field
+ */
+ public void setField(String field, String value) {
+ if ((field == null) || (value == null)) {
+ throw new NullPointerException(((field == null) ? "field " : "value ") + "must not be null");
+ }
+ fields.put(field, value);
+ }
+
+ /**
+ * Returns the value of the given field.
+ *
+ * @param field
+ * The name of the field
+ * @return The value of the field, or <code>null</code> if there is no such
+ * field
+ */
+ public String getField(String field) {
+ return fields.get(field);
+ }
+
+ /**
+ * Returns all fields of this message.
+ *
+ * @return All fields of this message
+ */
+ public Map<String, String> getFields() {
+ return Collections.unmodifiableMap(fields);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Iterator<String> iterator() {
+ return fields.keySet().iterator();
+ }
+
+ /**
+ * Sets the payload input stream of the message.
+ *
+ * @param payloadInputStream
+ * The payload input stream
+ */
+ public void setPayloadInputStream(InputStream payloadInputStream) {
+ this.payloadInputStream = payloadInputStream;
+ }
+
+ /**
+ * Writes this message to the given output stream. If the message has a
+ * payload (i.e. {@link #payloadInputStream} is not <code>null</code>) the
+ * payload is written to the given output stream after the message as well.
+ * That means that this method can only be called once because on the second
+ * invocation the payload input stream could not be read (again).
+ *
+ * @param outputStream
+ * The output stream to write the message to
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public void write(OutputStream outputStream) throws IOException {
+ writeLine(outputStream, name);
+ for (Entry<String, String> fieldEntry : fields.entrySet()) {
+ writeLine(outputStream, fieldEntry.getKey() + "=" + fieldEntry.getValue());
+ }
+ writeLine(outputStream, "EndMessage");
+ outputStream.flush();
+ if (payloadInputStream != null) {
+ FcpUtils.copy(payloadInputStream, outputStream);
+ outputStream.flush();
+ }
+ }
+
+ //
+ // PRIVATE METHODS
+ //
+
+ /**
+ * Writes the given line (followed by {@link #LINEFEED} to the given output
+ * stream, using UTF-8 as encoding.
+ *
+ * @param outputStream
+ * The output stream to write to
+ * @param line
+ * The line to write
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ private void writeLine(OutputStream outputStream, String line) throws IOException {
+ outputStream.write((line + LINEFEED).getBytes("UTF-8"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpTest.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests various commands and the FCP connection.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class FcpTest extends TestCase {
+
+ /** The FCP connection. */
+ private FcpConnection fcpConnection;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void setUp() throws Exception {
+ fcpConnection = new FcpConnection("wing");
+ fcpConnection.connect();
+ fcpConnection.sendMessage(new ClientHello("FcpTest"));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ fcpConnection.close();
+ }
+
+ /**
+ * Tests the FCP connection be simply {@link #setUp() setting it up} and
+ * {@link #tearDown() tearing it down} again.
+ */
+ public void testFcpConnection() {
+ /* do nothing. */
+ }
+
+ /**
+ * Generates an SSK key pair.
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws InterruptedException
+ * if {@link Object#wait()} wakes up spuriously
+ */
+ public void testGenerateSSK() throws IOException, InterruptedException {
+ final SSKKeypair[] keypair = new SSKKeypair[1];
+ FcpAdapter fcpAdapter = new FcpAdapter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
+ keypair[0] = sskKeypair;
+ synchronized (this) {
+ notify();
+ }
+ }
+ };
+ fcpConnection.addFcpListener(fcpAdapter);
+ synchronized (fcpAdapter) {
+ fcpConnection.sendMessage(new GenerateSSK());
+ fcpAdapter.wait();
+ }
+ assertNotNull("ssk keypair", keypair[0]);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpUtils.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.StringTokenizer;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Helper class with utility methods for the FCP protocol.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class FcpUtils {
+
+ /** Counter for unique identifiers. */
+ private static AtomicLong counter = new AtomicLong();
+
+ /**
+ * Returns a unique identifier.
+ *
+ * @return A unique identifier
+ */
+ public static String getUniqueIdentifier() {
+ return new StringBuilder().append(System.currentTimeMillis()).append('-').append(counter.getAndIncrement()).toString();
+ }
+
+ /**
+ * Parses an integer field, separated by ‘;’ and returns the parsed values.
+ *
+ * @param field
+ * The field to parse
+ * @return An array with the parsed values
+ * @throws NumberFormatException
+ * if a value can not be converted to a number
+ */
+ public static int[] decodeMultiIntegerField(String field) throws NumberFormatException {
+ StringTokenizer fieldTokens = new StringTokenizer(field, ";");
+ int[] result = new int[fieldTokens.countTokens()];
+ int counter = 0;
+ while (fieldTokens.hasMoreTokens()) {
+ String fieldToken = fieldTokens.nextToken();
+ result[counter++] = Integer.valueOf(fieldToken);
+ }
+ return result;
+ }
+
+ /**
+ * Encodes the given integer array into a string, separating the values by
+ * ‘;’.
+ *
+ * @param values
+ * The values to encode
+ * @return The encoded values
+ */
+ public static String encodeMultiIntegerField(int[] values) {
+ StringBuilder encodedField = new StringBuilder();
+ for (int value : values) {
+ if (encodedField.length() > 0) {
+ encodedField.append(';');
+ }
+ encodedField.append(value);
+ }
+ return encodedField.toString();
+ }
+
+ /**
+ * Encodes the given string array into a string, separating the values by
+ * ‘;’.
+ *
+ * @param values
+ * The values to encode
+ * @return The encoded values
+ */
+ public static String encodeMultiStringField(String[] values) {
+ StringBuilder encodedField = new StringBuilder();
+ for (String value : values) {
+ if (encodedField.length() > 0) {
+ encodedField.append(';');
+ }
+ encodedField.append(value);
+ }
+ return encodedField.toString();
+ }
+
+ /**
+ * Tries to parse the given string into an int, returning <code>-1</code> if
+ * the string can not be parsed.
+ *
+ * @param value
+ * The string to parse
+ * @return The parsed int, or <code>-1</code>
+ */
+ public static int safeParseInt(String value) {
+ return safeParseInt(value, -1);
+ }
+
+ /**
+ * Tries to parse the given string into an int, returning
+ * <code>defaultValue</code> if the string can not be parsed.
+ *
+ * @param value
+ * The string to parse
+ * @param defaultValue
+ * The value to return if the string can not be parsed.
+ * @return The parsed int, or <code>defaultValue</code>
+ */
+ public static int safeParseInt(String value, int defaultValue) {
+ try {
+ return Integer.valueOf(value);
+ } catch (NumberFormatException nfe1) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Tries to parse the given string into an long, returning <code>-1</code>
+ * if the string can not be parsed.
+ *
+ * @param value
+ * The string to parse
+ * @return The parsed long, or <code>-1</code>
+ */
+ public static long safeParseLong(String value) {
+ return safeParseLong(value, -1);
+ }
+
+ /**
+ * Tries to parse the given string into an long, returning
+ * <code>defaultValue</code> if the string can not be parsed.
+ *
+ * @param value
+ * The string to parse
+ * @param defaultValue
+ * The value to return if the string can not be parsed.
+ * @return The parsed long, or <code>defaultValue</code>
+ */
+ public static long safeParseLong(String value, long defaultValue) {
+ try {
+ return Integer.valueOf(value);
+ } catch (NumberFormatException nfe1) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Closes the given socket.
+ *
+ * @param socket
+ * The socket to close
+ */
+ public static void close(Socket socket) {
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (IOException ioe1) {
+ /* ignore. */
+ }
+ }
+ }
+
+ /**
+ * Closes the given Closeable.
+ *
+ * @param closeable
+ * The Closeable to close
+ */
+ public static void close(Closeable closeable) {
+ if (closeable != null) {
+ try {
+ closeable.close();
+ } catch (IOException ioe1) {
+ /* ignore. */
+ }
+ }
+ }
+
+ /**
+ * Copies as many bytes as possible (i.e. until {@link InputStream#read()}
+ * returns <code>-1</code>) from the source input stream to the destination
+ * output stream.
+ *
+ * @param source
+ * The input stream to read from
+ * @param destination
+ * The output stream to write to
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public static void copy(InputStream source, OutputStream destination) throws IOException {
+ copy(source, destination, -1);
+ }
+
+ /**
+ * Copies <code>length</code> bytes from the source input stream to the
+ * destination output stream. If <code>length</code> is <code>-1</code> as
+ * much bytes as possible will be copied (i.e. until
+ * {@link InputStream#read()} returns <code>-1</code> to signal the end of
+ * the stream).
+ *
+ * @param source
+ * The input stream to read from
+ * @param destination
+ * The output stream to write to
+ * @param length
+ * The number of bytes to copy
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public static void copy(InputStream source, OutputStream destination, long length) throws IOException {
+ copy(source, destination, length, 1 << 16);
+ }
+
+ /**
+ * Copies <code>length</code> bytes from the source input stream to the
+ * destination output stream. If <code>length</code> is <code>-1</code> as
+ * much bytes as possible will be copied (i.e. until
+ * {@link InputStream#read()} returns <code>-1</code> to signal the end of
+ * the stream).
+ *
+ * @param source
+ * The input stream to read from
+ * @param destination
+ * The output stream to write to
+ * @param length
+ * The number of bytes to copy
+ * @param bufferSize
+ * The buffer size
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public static void copy(InputStream source, OutputStream destination, long length, int bufferSize) throws IOException {
+ long remaining = length;
+ byte[] buffer = new byte[bufferSize];
+ int read = 0;
+ while ((remaining == -1) || (remaining > 0)) {
+ read = source.read(buffer, 0, ((remaining > bufferSize) || (remaining == -1)) ? bufferSize : (int) remaining);
+ if (read == -1) {
+ if (length == -1) {
+ return;
+ }
+ throw new EOFException("stream reached eof");
+ }
+ destination.write(buffer, 0, read);
+ remaining -= read;
+ }
+ }
+
+ /**
+ * This input stream stores the content of another input stream either in a
+ * file or in memory, depending on the length of the input stream.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ public static class TempInputStream extends InputStream {
+
+ /** The default maximum lenght for in-memory storage. */
+ public static final long MAX_LENGTH_MEMORY = 65536;
+
+ /** The temporary file to read from. */
+ private final File tempFile;
+
+ /** The input stream that reads from the file. */
+ private final InputStream fileInputStream;
+
+ /** The input stream that reads from memory. */
+ private final InputStream memoryInputStream;
+
+ /**
+ * Creates a new temporary input stream that stores the given input
+ * stream in a temporary file.
+ *
+ * @param originalInputStream
+ * The original input stream
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public TempInputStream(InputStream originalInputStream) throws IOException {
+ this(originalInputStream, -1);
+ }
+
+ /**
+ * Creates a new temporary input stream that stores the given input
+ * stream in memory if it is shorter than {@link #MAX_LENGTH_MEMORY},
+ * otherwise it is stored in a file.
+ *
+ * @param originalInputStream
+ * The original input stream
+ * @param length
+ * The length of the input stream
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public TempInputStream(InputStream originalInputStream, long length) throws IOException {
+ this(originalInputStream, length, MAX_LENGTH_MEMORY);
+ }
+
+ /**
+ * Creates a new temporary input stream that stores the given input
+ * stream in memory if it is shorter than <code>maxMemoryLength</code>,
+ * otherwise it is stored in a file.
+ *
+ * @param originalInputStream
+ * The original input stream
+ * @param length
+ * The length of the input stream
+ * @param maxMemoryLength
+ * The maximum length to store in memory
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public TempInputStream(InputStream originalInputStream, long length, long maxMemoryLength) throws IOException {
+ if ((length > -1) && (length <= maxMemoryLength)) {
+ ByteArrayOutputStream memoryOutputStream = new ByteArrayOutputStream((int) length);
+ try {
+ FcpUtils.copy(originalInputStream, memoryOutputStream, length, (int) length);
+ } finally {
+ memoryOutputStream.close();
+ }
+ tempFile = null;
+ fileInputStream = null;
+ memoryInputStream = new ByteArrayInputStream(memoryOutputStream.toByteArray());
+ } else {
+ tempFile = File.createTempFile("temp-", ".bin");
+ tempFile.deleteOnExit();
+ FileOutputStream fileOutputStream = null;
+ try {
+ fileOutputStream = new FileOutputStream(tempFile);
+ FcpUtils.copy(originalInputStream, fileOutputStream);
+ fileInputStream = new FileInputStream(tempFile);
+ } finally {
+ FcpUtils.close(fileOutputStream);
+ }
+ memoryInputStream = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int available() throws IOException {
+ if (memoryInputStream != null) {
+ return memoryInputStream.available();
+ }
+ return fileInputStream.available();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void close() throws IOException {
+ if (memoryInputStream != null) {
+ memoryInputStream.close();
+ return;
+ }
+ tempFile.delete();
+ fileInputStream.close();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void mark(int readlimit) {
+ if (memoryInputStream != null) {
+ memoryInputStream.mark(readlimit);
+ return;
+ }
+ fileInputStream.mark(readlimit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean markSupported() {
+ if (memoryInputStream != null) {
+ return memoryInputStream.markSupported();
+ }
+ return fileInputStream.markSupported();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int read() throws IOException {
+ if (memoryInputStream != null) {
+ return memoryInputStream.read();
+ }
+ return fileInputStream.read();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int read(byte[] b) throws IOException {
+ if (memoryInputStream != null) {
+ return memoryInputStream.read(b);
+ }
+ return fileInputStream.read(b);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (memoryInputStream != null) {
+ return memoryInputStream.read(b, off, len);
+ }
+ return fileInputStream.read(b, off, len);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void reset() throws IOException {
+ if (memoryInputStream != null) {
+ memoryInputStream.reset();
+ return;
+ }
+ fileInputStream.reset();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public long skip(long n) throws IOException {
+ if (memoryInputStream != null) {
+ return memoryInputStream.skip(n);
+ }
+ return fileInputStream.skip(n);
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FileEntry.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Container class for file entry data.
+ *
+ * @see ClientPutComplexDir#addFileEntry(FileEntry)
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public abstract class FileEntry {
+
+ /** The name of the file. */
+ protected final String name;
+
+ /** The upload source of the file. */
+ protected final UploadFrom uploadFrom;
+
+ /**
+ * Creates a new file entry with the given name and upload source.
+ *
+ * @param name
+ * The name of the file
+ * @param uploadFrom
+ * The upload source of the file
+ */
+ protected FileEntry(String name, UploadFrom uploadFrom) {
+ this.name = name;
+ this.uploadFrom = uploadFrom;
+ }
+
+ /**
+ * Creates a new file entry for a file that should be transmitted to the
+ * node in the payload of the message.
+ *
+ * @param name
+ * The name of the file
+ * @param contentType
+ * The content type of the file, or <code>null</code> to let the
+ * node auto-detect it
+ * @param length
+ * The length of the file
+ * @param dataInputStream
+ * The input stream of the file
+ * @return A file entry
+ */
+ public static FileEntry createDirectFileEntry(String name, String contentType, long length, InputStream dataInputStream) {
+ return new DirectFileEntry(name, contentType, length, dataInputStream);
+ }
+
+ /**
+ * Creates a new file entry for a file that should be uploaded from disk.
+ *
+ * @param name
+ * The name of the file
+ * @param filename
+ * The name of the file on disk
+ * @param contentType
+ * The content type of the file, or <code>null</code> to let the
+ * node auto-detect it
+ * @param length
+ * The length of the file, or <code>-1</code> to not specify a
+ * size
+ * @return A file entry
+ */
+ public static FileEntry createDiskFileEntry(String name, String filename, String contentType, long length) {
+ return new DiskFileEntry(name, filename, contentType, length);
+ }
+
+ /**
+ * Creates a new file entry for a file that redirects to another URI.
+ *
+ * @param name
+ * The name of the file
+ * @param targetURI
+ * The target URI of the redirect
+ * @return A file entry
+ */
+ public static FileEntry createRedirectFileEntry(String name, String targetURI) {
+ return new RedirectFileEntry(name, targetURI);
+ }
+
+ /**
+ * Returns the fields for this file entry.
+ *
+ * @return The fields for this file entry
+ */
+ abstract Map<String, String> getFields();
+
+ /**
+ * A file entry for a file that should be transmitted in the payload of the
+ * {@link ClientPutComplexDir} message.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ static class DirectFileEntry extends FileEntry {
+
+ /** The content type of the data. */
+ private final String contentType;
+
+ /** The length of the data. */
+ private final long length;
+
+ /** The input stream of the data. */
+ private final InputStream inputStream;
+
+ /**
+ * Creates a new direct file entry with content type auto-detection.
+ *
+ * @param name
+ * The name of the file
+ * @param length
+ * The length of the file
+ * @param inputStream
+ * The input stream of the file
+ */
+ public DirectFileEntry(String name, long length, InputStream inputStream) {
+ this(name, null, length, inputStream);
+ }
+
+ /**
+ * Creates a new direct file entry.
+ *
+ * @param name
+ * The name of the file
+ * @param contentType
+ * The content type of the file, or <code>null</code> to let
+ * the node auto-detect it
+ * @param length
+ * The length of the file
+ * @param inputStream
+ * The input stream of the file
+ */
+ public DirectFileEntry(String name, String contentType, long length, InputStream inputStream) {
+ super(name, UploadFrom.direct);
+ this.contentType = contentType;
+ this.length = length;
+ this.inputStream = inputStream;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ Map<String, String> getFields() {
+ Map<String, String> fields = new HashMap<String, String>();
+ fields.put("Name", name);
+ fields.put("UploadFrom", String.valueOf(uploadFrom));
+ fields.put("DataLength", String.valueOf(length));
+ if (contentType != null) {
+ fields.put("Metadata.ContentType", contentType);
+ }
+ return fields;
+ }
+
+ /**
+ * Returns the input stream of the file.
+ *
+ * @return The input stream of the file
+ */
+ InputStream getInputStream() {
+ return inputStream;
+ }
+
+ }
+
+ /**
+ * A file entry for a file that should be uploaded from the disk.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ static class DiskFileEntry extends FileEntry {
+
+ /** The name of the on-disk file. */
+ private final String filename;
+
+ /** The content type of the file. */
+ private final String contentType;
+
+ /** The length of the file. */
+ private final long length;
+
+ /**
+ * Creates a new disk file entry.
+ *
+ * @param name
+ * The name of the file
+ * @param filename
+ * The name of the on-disk file
+ * @param length
+ * The length of the file
+ */
+ public DiskFileEntry(String name, String filename, long length) {
+ this(name, filename, null, length);
+ }
+
+ /**
+ * Creates a new disk file entry.
+ *
+ * @param name
+ * The name of the file
+ * @param filename
+ * The name of the on-disk file
+ * @param contentType
+ * The content type of the file, or <code>null</code> to let
+ * the node auto-detect it
+ * @param length
+ * The length of the file
+ */
+ public DiskFileEntry(String name, String filename, String contentType, long length) {
+ super(name, UploadFrom.disk);
+ this.filename = filename;
+ this.contentType = contentType;
+ this.length = length;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ Map<String, String> getFields() {
+ Map<String, String> fields = new HashMap<String, String>();
+ fields.put("Name", name);
+ fields.put("UploadFrom", String.valueOf(uploadFrom));
+ fields.put("Filename", filename);
+ if (length > -1) {
+ fields.put("DataSize", String.valueOf(length));
+ }
+ if (contentType != null) {
+ fields.put("Metadata.ContentType", contentType);
+ }
+ return fields;
+ }
+
+ }
+
+ /**
+ * A file entry for a file that redirects to another URI.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ static class RedirectFileEntry extends FileEntry {
+
+ /** The target URI of the redirect. */
+ private String targetURI;
+
+ /**
+ * Creates a new redirect file entry.
+ *
+ * @param name
+ * The name of the file
+ * @param targetURI
+ * The target URI of the redirect
+ */
+ public RedirectFileEntry(String name, String targetURI) {
+ super(name, UploadFrom.redirect);
+ this.targetURI = targetURI;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ Map<String, String> getFields() {
+ Map<String, String> fields = new HashMap<String, String>();
+ fields.put("Name", name);
+ fields.put("UploadFrom", String.valueOf(uploadFrom));
+ fields.put("TargetURI", targetURI);
+ return fields;
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FinishedCompression.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “FinishedCompression” message signals the client that the compression of
+ * the request data has been finished.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - GenerateSSK.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “GenerateSSK” message. This message tells the node to generate a new SSK
+ * key pair.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - GetConfig.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “GetConfig” command tells the node to send its configuration to the
+ * client.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class GetConfig extends FcpMessage {
+
+ /**
+ * Creates a new “GetConfig” command.
+ */
+ public GetConfig() {
+ super("GetConfig");
+ }
+
+ /**
+ * Sets whether the {@link ConfigData} result message shall include the
+ * current values.
+ *
+ * @param withCurrent
+ * <code>true</code> to include current values in the result,
+ * <code>false</code> otherwise
+ */
+ public void setWithCurrent(boolean withCurrent) {
+ setField("WithCurrent", String.valueOf(withCurrent));
+ }
+
+ /**
+ * Sets whether the {@link ConfigData} result message shall include the
+ * short descriptions.
+ *
+ * @param withShortDescription
+ * <code>true</code> to include the short descriptions in the
+ * result, <code>false</code> otherwise
+ */
+ public void setWithShortDescription(boolean withShortDescription) {
+ setField("WithShortDescription", String.valueOf(withShortDescription));
+ }
+
+ /**
+ * Sets whether the {@link ConfigData} result message shall include the long
+ * descriptions.
+ *
+ * @param withLongDescription
+ * <code>true</code> to include the long descriptions in the
+ * result, <code>false</code> otherwise
+ */
+ public void setWithLongDescription(boolean withLongDescription) {
+ setField("WithLongDescription", String.valueOf(withLongDescription));
+ }
+
+ /**
+ * Sets whether the {@link ConfigData} result message shall include the data
+ * types.
+ *
+ * @param withDataTypes
+ * <code>true</code> to include the data types in the result,
+ * <code>false</code> otherwise
+ */
+ public void setWithDataTypes(boolean withDataTypes) {
+ setField("WithDataTypes", String.valueOf(withDataTypes));
+ }
+
+ /**
+ * Sets whether the {@link ConfigData} result message shall include the
+ * defaults.
+ *
+ * @param setWithDefaults
+ * <code>true</code> to include the defaults in the result,
+ * <code>false</code> otherwise
+ */
+ public void setWithDefaults(boolean setWithDefaults) {
+ setField("WithDefaults", String.valueOf(setWithDefaults));
+ }
+
+ /**
+ * Sets whether the {@link ConfigData} result message shall include the sort
+ * order.
+ *
+ * @param withSortOrder
+ * <code>true</code> to include the sort order in the result,
+ * <code>false</code> otherwise
+ */
+ public void setWithSortOrder(boolean withSortOrder) {
+ setField("WithSortOrder", String.valueOf(withSortOrder));
+ }
+
+ /**
+ * Sets whether the {@link ConfigData} result message shall include the
+ * expert flag.
+ *
+ * @param withExpertFlag
+ * <code>true</code> to include the expert flag in the result,
+ * <code>false</code> otherwise
+ */
+ public void setWithExpertFlag(boolean withExpertFlag) {
+ setField("WithExpertFlag", String.valueOf(withExpertFlag));
+ }
+
+ /**
+ * Sets whether the {@link ConfigData} result message shall include the
+ * force-write flag.
+ *
+ * @param withForceWriteFlag
+ * <code>true</code> to include the force-write flag in the
+ * result, <code>false</code> otherwise
+ */
+ public void setWithForceWriteFlag(boolean withForceWriteFlag) {
+ setField("WithForceWriteFlag", String.valueOf(withForceWriteFlag));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - GetFailed.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * The “GetFailed” message signals the client that a {@link ClientGet} request
+ * has failed. This also means that no further progress messages for that
+ * request will be sent.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class GetFailed extends BaseMessage {
+
+ /**
+ * Creates a new “GetFailed” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ GetFailed(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the code of the error.
+ *
+ * @return The code of the error, or <code>-1</code> if the error code could
+ * not be parsed
+ */
+ public int getCode() {
+ return FcpUtils.safeParseInt(getField("Code"));
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns whether the request is on the global queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on the client-local queue
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+ /**
+ * Returns the description of the error code.
+ *
+ * @return The description of the error code
+ */
+ public String getCodeDescription() {
+ return getField("CodeDescription");
+ }
+
+ /**
+ * Returns the extra description of the error.
+ *
+ * @return The extra description of the error
+ */
+ public String getExtraDescription() {
+ return getField("ExtraDescription");
+ }
+
+ /**
+ * Returns the short description of the error.
+ *
+ * @return The short description of the error
+ */
+ public String getShortCodeDescription() {
+ return getField("ShortCodeDescription");
+ }
+
+ /**
+ * Returns the expected data length, if already knows.
+ *
+ * @return The expected data length, or <code>-1</code> if the length could
+ * not be parsed
+ */
+ public long getExpectedDataLength() {
+ return FcpUtils.safeParseLong(getField("ExpectedDataLength"));
+ }
+
+ /**
+ * Returns the expected content type of the request.
+ *
+ * @return The expected content type
+ */
+ public String getExpectedMetadataContentType() {
+ return getField("ExpectedMetadata.ContentType");
+ }
+
+ /**
+ * Returns whether the expected values (see {@link #getExpectedDataLength()}
+ * and {@link #getExpectedMetadataContentType()}) have already been
+ * finalized and can be trusted. If the values have not been finalized that
+ * can change over time.
+ *
+ * @return <code>true</code> if the expected values have already been
+ * finalized, <code>false</code> otherwise
+ */
+ public boolean isFinalizedExpected() {
+ return Boolean.valueOf(getField("FinalizedExpected"));
+ }
+
+ /**
+ * Returns the URI the request is redirected to (in case of a request for a
+ * USK). This is returned so that client applications know that the URI of
+ * the key has updated.
+ *
+ * @return The URI the request was redirected to
+ */
+ public String getRedirectURI() {
+ return getField("RedirectURI");
+ }
+
+ /**
+ * Returns whether the request failed fatally. If a request fails fatally it
+ * can never complete, even with inifinite retries.
+ *
+ * @return <code>true</code> if the request failed fatally,
+ * <code>false</code> otherwise
+ */
+ public boolean isFatal() {
+ return Boolean.valueOf(getField("Fatal"));
+ }
+
+ /**
+ * Returns a list of complex error codes with the message. Use
+ * {@link #getComplexErrorDescription(int)} and
+ * {@link #getComplexErrorCount(int)} to get details.
+ *
+ * @return A list of complex error codes
+ */
+ public int[] getComplexErrorCodes() {
+ Map<String, String> allFields = getFields();
+ List<Integer> errorCodeList = new ArrayList<Integer>();
+ for (Entry<String, String> field : allFields.entrySet()) {
+ String fieldKey = field.getKey();
+ if (fieldKey.startsWith("Errors.")) {
+ int nextDot = fieldKey.indexOf('.', 7);
+ if (nextDot > -1) {
+ int errorCode = FcpUtils.safeParseInt(fieldKey.substring(7, nextDot));
+ if (errorCode != -1) {
+ errorCodeList.add(errorCode);
+ }
+ }
+ }
+ }
+ int[] errorCodes = new int[errorCodeList.size()];
+ int errorIndex = 0;
+ for (int errorCode : errorCodeList) {
+ errorCodes[errorIndex++] = errorCode;
+ }
+ return errorCodes;
+ }
+
+ /**
+ * Returns the description of the complex error. You should only hand it
+ * error codes you got from {@link #getComplexErrorCodes()}!
+ *
+ * @param errorCode
+ * The error code
+ * @return The description of the complex error
+ */
+ public String getComplexErrorDescription(int errorCode) {
+ return getField("Errors." + errorCode + ".Description");
+ }
+
+ /**
+ * Returns the count of the complex error. You should only hand it error
+ * codes you got from {@link #getComplexErrorCodes()}!
+ *
+ * @param errorCode
+ * The error code
+ * @return The count of the complex error, or <code>-1</code> if the count
+ * could not be parsed
+ */
+ public int getComplexErrorCount(int errorCode) {
+ return FcpUtils.safeParseInt(getField("Errors." + errorCode + ".Count"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - GetNode.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “GetNode” command returns the darknet or opennet noderef of the node,
+ * optionally including private and volatile data.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class GetNode extends FcpMessage {
+
+ /**
+ * Creates a “GetNode” command that returns the darknet noderef of the node.
+ */
+ public GetNode() {
+ this(null, null, null);
+ }
+
+ /**
+ * Creates a “GetNode” command that returns the request noderef of the node,
+ * including private and volatile data, if requested. If any of the Boolean
+ * parameters are <code>null</code> the parameter is ignored and the node’s
+ * default value is used.
+ *
+ * @param giveOpennetRef
+ * <code>true</code> to request the opennet noderef,
+ * <code>false</code> for darknet
+ * @param withPrivate
+ * <code>true</code> to include private data in the noderef
+ * @param withVolatile
+ * <code>true</code> to include volatile data in the noderef
+ */
+ public GetNode(Boolean giveOpennetRef, Boolean withPrivate, Boolean withVolatile) {
+ super("GetNode");
+ if (giveOpennetRef != null) {
+ setField("GiveOpennetRef", String.valueOf(giveOpennetRef));
+ }
+ if (withPrivate != null) {
+ setField("WithPrivate", String.valueOf(withPrivate));
+ }
+ if (withVolatile != null) {
+ setField("WithVolatile", String.valueOf(withVolatile));
+ }
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - GetPluginInfo.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “GetPluginInfo” message requests information about a plugin from the
+ * node, which will response with a {@link PluginInfo} message.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class GetPluginInfo extends FcpMessage {
+
+ /**
+ * Creates a new “GetPluginInfo” message.
+ *
+ * @param pluginName
+ * The name of the plugin
+ * @param identifier
+ * The identifier of the request
+ */
+ public GetPluginInfo(String pluginName, String identifier) {
+ super("GetPluginInfo");
+ setField("PluginName", pluginName);
+ setField("Identifier", identifier);
+ }
+
+ /**
+ * Sets whether detailed information about the plugin is wanted.
+ *
+ * @param detailed
+ * <code>true</code> to request detailed information about the
+ * plugin, <code>false</code> otherwise
+ */
+ public void setDetailed(boolean detailed) {
+ setField("Detailed", String.valueOf(detailed));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - GetRequestStatus.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “GetRequestStatus” message is used request status information about a
+ * running request. It is also the only way to trigger a download of a persisted
+ * completed {@link ClientGet} with a return type of {@link ReturnType#direct}.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class GetRequestStatus extends FcpMessage {
+
+ /**
+ * Creates a new “GetRequestStatus” message.
+ *
+ * @param identifier
+ * The identifier of the request
+ */
+ public GetRequestStatus(String identifier) {
+ super("GetRequestStatus");
+ setField("Identifier", identifier);
+ }
+
+ /**
+ * Sets whether the request is on the global queue.
+ *
+ * @param global
+ * <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on the client-local queue
+ */
+ public void setGlobal(boolean global) {
+ setField("Global", String.valueOf(global));
+ }
+
+ /**
+ * Sets whether the omit the transmission of the request data in a
+ * {@link AllData} message.
+ *
+ * @param onlyData
+ * <code>true</code> to skip transmission of data,
+ * <code>false</code> to download data
+ */
+ public void setOnlyData(boolean onlyData) {
+ setField("OnlyData", String.valueOf(onlyData));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - IdentifierCollision.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “IdentifierCollision” message signals the client that the identifier
+ * chosen for a request is already existing.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class IdentifierCollision extends BaseMessage {
+
+ /**
+ * Creates a new “IdentifierCollision” message that wraps the received
+ * message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ IdentifierCollision(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns whether the request is on the global queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on the client-local queue
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ListPeer.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ListPeer” request asks the node about the details of a given peer.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ListPeer extends FcpMessage {
+
+ /**
+ * Creates a new “ListPeer” request that returns information about the node
+ * specified by <code>nodeIdentifier</code>. <code>nodeIdentifier</code> can
+ * be of several formats: The node’s name, its identity, or its IP address
+ * and port (connection with a ‘:’).
+ *
+ * @param nodeIdentifier
+ * The identifier of the node to get details about
+ */
+ public ListPeer(String nodeIdentifier) {
+ super("ListPeer");
+ setField("NodeIdentifier", nodeIdentifier);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ListPeerNotes.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ListPeerNodes” request tells the node to list all notes that have been
+ * entered for a node. Note that notes are only supported for darknet nodes.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ListPeers.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ListPeer” requests asks the node for a list of all peers it has.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ListPeers extends FcpMessage {
+
+ /**
+ * Creates a new “ListPeers” request that only includes basic data of the
+ * peers.
+ *
+ * @param identifier
+ * The identifier of the request
+ */
+ public ListPeers(String identifier) {
+ this(identifier, false, false);
+ }
+
+ /**
+ * Creates a new “ListPeers” request that includes wanted data of the peers.
+ *
+ * @param identifier
+ * The identifier of the request
+ * @param withMetadata
+ * If <code>true</code> metadata of the peers is included in the
+ * reply
+ * @param withVolatile
+ * if <code>true</code> volatile data of the peers is included in
+ * the reply
+ */
+ public ListPeers(String identifier, boolean withMetadata, boolean withVolatile) {
+ super("ListPeers");
+ setField("Identifier", identifier);
+ setField("WithMetadata", String.valueOf(withMetadata));
+ setField("WithVolatile", String.valueOf(withVolatile));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ListPersistentRequests.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Command to tell the node to list all persistent requests from the current
+ * queue, which is either the global queue or the client-local queue, depending
+ * on your {@link WatchGlobal} status.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ListPersistentRequests extends FcpMessage {
+
+ /**
+ * Creates a new “ListPersistentRequests” command that lists all persistent
+ * requests in the current queue.
+ */
+ public ListPersistentRequests() {
+ super("ListPersistentRequests");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ModifyConfig.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ModifyConfig” message is used to change the node’s configuration.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ModifyPeer.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ModifyPeer” request lets you modify certain properties of a peer.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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));
+ }
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ModifyPeerNote.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ModifyPeerNote” command modifies a peer note.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ModifyPersistentRequest.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “ModifyPersistentRequest” is used to modify certain properties of a
+ * persistent request while it is running.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ModifyPersistentRequest extends FcpMessage {
+
+ /**
+ * Creates a new “ModifyPersistentRequest” that changes the specified
+ * request.
+ *
+ * @param requestIdentifier
+ * The identifier of the request
+ * @param global
+ * <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on the client-local queue
+ */
+ public ModifyPersistentRequest(String requestIdentifier, boolean global) {
+ super("ModifyPersistentRequest");
+ setField("Identifier", requestIdentifier);
+ setField("Global", String.valueOf(global));
+ }
+
+ /**
+ * Sets the new client token of the request.
+ *
+ * @param newClientToken
+ * The new client token of the request
+ */
+ public void setClientToken(String newClientToken) {
+ setField("ClientToken", newClientToken);
+ }
+
+ /**
+ * Sets the new priority of the request.
+ *
+ * @param newPriority
+ * The new priority of the request
+ */
+ public void setPriority(Priority newPriority) {
+ setField("PriorityClass", String.valueOf(newPriority));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - NodeData.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “NodeData” contains the noderef of the node, along with additional data.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class NodeData extends BaseMessage {
+
+ /** The noderef of the node. */
+ private final NodeRef nodeRef;
+
+ /**
+ * Creates a new “NodeData” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ NodeData(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ nodeRef = new NodeRef(receivedMessage);
+ }
+
+ /**
+ * Returns the noderef of the node.
+ *
+ * @return The noderef of the node
+ */
+ public NodeRef getNodeRef() {
+ return nodeRef;
+ }
+
+ /**
+ * Returns the last good version, i.e. the oldest version the node will
+ * connect to.
+ *
+ * @return The last good version
+ */
+ public Version getLastGoodVersion() {
+ return nodeRef.getLastGoodVersion();
+ }
+
+ /**
+ * Returns the signature of the noderef.
+ *
+ * @return The signature of the noderef
+ */
+ public String getSignature() {
+ return nodeRef.getSignature();
+ }
+
+ /**
+ * Returns whether the noderef is the opennet noderef of the node
+ *
+ * @return <code>true</code> if the noderef is the opennet noderef of the
+ * node, <code>false</code> otherwise
+ */
+ public boolean isOpennet() {
+ return nodeRef.isOpennet();
+ }
+
+ /**
+ * Returns the identity of the node
+ *
+ * @return The identity of the node
+ */
+ public String getIdentity() {
+ return nodeRef.getIdentity();
+ }
+
+ /**
+ * Returns the name of the node.
+ *
+ * @return The name of the node
+ */
+ public String getMyName() {
+ return nodeRef.getMyName();
+ }
+
+ /**
+ * Returns the version of the node.
+ *
+ * @return The version of the node
+ */
+ public Version getVersion() {
+ return nodeRef.getVersion();
+ }
+
+ /**
+ * Returns IP addresses and port number of the node.
+ *
+ * @return The IP addresses and port numbers of the node
+ */
+ public String getPhysicalUDP() {
+ return nodeRef.getPhysicalUDP();
+ }
+
+ /**
+ * Returns the ARK of the node.
+ *
+ * @return The ARK of the node
+ */
+ public ARK getARK() {
+ return nodeRef.getARK();
+ }
+
+ /**
+ * Returns the public key of the node.
+ *
+ * @return The public key of the node
+ */
+ public String getDSAPublicKey() {
+ return nodeRef.getDSAPublicKey();
+ }
+
+ /**
+ * Returns the private key of the node.
+ *
+ * @return The private key of the node
+ */
+ public String getDSKPrivateKey() {
+ return getField("dsaPrivKey.x");
+ }
+
+ /**
+ * Returns the DSA group of the node.
+ *
+ * @return The DSA group of the node
+ */
+ public DSAGroup getDSAGroup() {
+ return nodeRef.getDSAGroup();
+ }
+
+ /**
+ * Returns the negotiation types supported by the node.
+ *
+ * @return The node’s supported negotiation types
+ */
+ public int[] getNegotiationTypes() {
+ return nodeRef.getNegotiationTypes();
+ }
+
+ /**
+ * Returns one of the volatile fields from the message. The given field name
+ * is prepended with “volatile.” so if you want to get the value of the
+ * field with the name “volatile.freeJavaMemory” you only need to specify
+ * “freeJavaMemory”.
+ *
+ * @param field
+ * The name of the field
+ * @return The value of the field, or <code>null</code> if there is no such
+ * field
+ */
+ public String getVolatile(String field) {
+ return getField("volatile." + field);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - NodeHello.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Some convenience methods for parsing a “NodeHello” message from the node.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class NodeHello extends BaseMessage {
+
+ /**
+ * Createa a new “NodeHello” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received FCP message
+ */
+ NodeHello(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the build of the node. This may not be a number but also a string
+ * like “@custom@” in case you built the node yourself.
+ *
+ * @return The build of the node
+ */
+ public String getBuild() {
+ return getField("Build");
+ }
+
+ /**
+ * Returns the build number of the node. This may not be a number but also a
+ * string like “@custom@” in case you built the node yourself.
+ *
+ * @return The build number of the node, or <code>-1</code> if the build
+ * number could not be determined
+ */
+ public int getBuildNumber() {
+ return FcpUtils.safeParseInt(getBuild());
+ }
+
+ /**
+ * Returns the number of compression codecs.
+ *
+ * @return The number of compression codecs
+ */
+ public String getCompressionCodecs() {
+ return getField("CompressionCodecs");
+ }
+
+ /**
+ * Returns the number of compression codecs.
+ *
+ * @return The number of compression codecs, or <code>-1</code> if the
+ * number of compression codecs could not be determined
+ */
+ public int getCompressionCodecsNumber() {
+ return FcpUtils.safeParseInt(getCompressionCodecs());
+ }
+
+ /**
+ * Returns the unique connection identifier.
+ *
+ * @return The connection identifier
+ */
+ public String getConnectionIdentifier() {
+ return getField("ConnectionIdentifier");
+ }
+
+ /**
+ * Returns the build of the external library file.
+ *
+ * @return The build of the external library file
+ */
+ public String getExtBuild() {
+ return getField("ExtBuild");
+ }
+
+ /**
+ * Returns the build number of the external library file.
+ *
+ * @return The build number of the external library file, or <code>-1</code>
+ * if the build number could not be determined
+ */
+ public int getExtBuildNumber() {
+ return FcpUtils.safeParseInt(getExtBuild());
+ }
+
+ /**
+ * Returns the revision of the external library file.
+ *
+ * @return The revision of the external library file
+ */
+ public String getExtRevision() {
+ return getField("ExtRevision");
+ }
+
+ /**
+ * Returns the revision number of the external library file.
+ *
+ * @return The revision number of the external library file, or
+ * <code>-1</code> if the revision number could not be determined
+ */
+ public int getExtRevisionNumber() {
+ return FcpUtils.safeParseInt(getExtRevision());
+ }
+
+ /**
+ * Returns the FCP version the node speaks.
+ *
+ * @return The FCP version the node speaks
+ */
+ public String getFCPVersion() {
+ return getField("FCPVersion");
+ }
+
+ /**
+ * Returns the make of the node, e.g. “Fred” (freenet reference
+ * implementation).
+ *
+ * @return The make of the node
+ */
+ public String getNode() {
+ return getField("Node");
+ }
+
+ /**
+ * Returns the language of the node as 2-letter code, e.g. “en” or “de”.
+ *
+ * @return The language of the node
+ */
+ public String getNodeLanguage() {
+ return getField("NodeLanguage");
+ }
+
+ /**
+ * Returns the revision of the node.
+ *
+ * @return The revision of the node
+ */
+ public String getRevision() {
+ return getField("Revision");
+ }
+
+ /**
+ * Returns the revision number of the node.
+ *
+ * @return The revision number of the node, or <code>-1</code> if the
+ * revision number coult not be determined
+ */
+ public int getRevisionNumber() {
+ return FcpUtils.safeParseInt(getRevision());
+ }
+
+ /**
+ * Returns whether the node is currently is testnet mode.
+ *
+ * @return <code>true</code> if the node is currently in testnet mode,
+ * <code>false</code> otherwise
+ */
+ public boolean getTestnet() {
+ return Boolean.valueOf(getField("Testnet"));
+ }
+
+ /**
+ * Returns the version of the node.
+ *
+ * @return The version of the node
+ */
+ public String getVersion() {
+ return getField("Version");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - NodeRef.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A reference for a node. The noderef contains all data that is necessary to
+ * establish a trusted and secure connection to the node.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class NodeRef {
+
+ /** The identity of the node. */
+ private String identity;
+
+ /** Whether the node is an opennet peer. */
+ private boolean opennet;
+
+ /** The name of the node. */
+ private String name;
+
+ /** The location of the node. */
+ private double location;
+
+ /** The IP addresses and ports of the node. */
+ private String physicalUDP;
+
+ /** The ARK of the node. */
+ private ARK ark;
+
+ /** The public DSA key of the node. */
+ private String dsaPublicKey;
+
+ /** The DSA group of the node. */
+ private DSAGroup dsaGroup;
+
+ /** The node’s supported negotiation types. */
+ private int[] negotiationTypes;
+
+ /** The version of the node. */
+ private Version version;
+
+ /** The oldest version the node will connect to. */
+ private Version lastGoodVersion;
+
+ /** Whether the node is a testnet node. */
+ private boolean testnet;
+
+ /** The signature of the reference. */
+ private String signature;
+
+ /**
+ * Creates a new, empty noderef.
+ */
+ public NodeRef() {
+ /* intentionally left blank. */
+ }
+
+ /**
+ * Creates a new noderef that is initialized with fields from the given
+ * message.
+ *
+ * @param fromMessage
+ * The message to get initial values for the noderef from
+ */
+ public NodeRef(FcpMessage fromMessage) {
+ identity = fromMessage.getField("identity");
+ opennet = Boolean.valueOf(fromMessage.getField("opennet"));
+ name = fromMessage.getField("myName");
+ if (fromMessage.hasField("location")) {
+ location = Double.valueOf(fromMessage.getField("location"));
+ }
+ physicalUDP = fromMessage.getField("physical.udp");
+ ark = new ARK(fromMessage.getField("ark.pubURI"), fromMessage.getField("ark.privURI"), fromMessage.getField("ark.number"));
+ dsaPublicKey = fromMessage.getField("dsaPubKey.y");
+ dsaGroup = new DSAGroup(fromMessage.getField("dsaGroup.b"), fromMessage.getField("dsaGroup.p"), fromMessage.getField("dsaGroup.q"));
+ negotiationTypes = FcpUtils.decodeMultiIntegerField(fromMessage.getField("auth.negTypes"));
+ version = new Version(fromMessage.getField("version"));
+ lastGoodVersion = new Version(fromMessage.getField("lastGoodVersion"));
+ testnet = Boolean.valueOf(fromMessage.getField("testnet"));
+ signature = fromMessage.getField("sig");
+ }
+
+ /**
+ * Returns the identity of the node.
+ *
+ * @return The identity of the node
+ */
+ public String getIdentity() {
+ return identity;
+ }
+
+ /**
+ * Sets the identity of the node.
+ *
+ * @param identity
+ * The identity of the node
+ */
+ public void setIdentity(String identity) {
+ this.identity = identity;
+ }
+
+ /**
+ * Returns whether the node is an opennet peer.
+ *
+ * @return <code>true</code> if the node is an opennet peer,
+ * <code>false</code> otherwise
+ */
+ public boolean isOpennet() {
+ return opennet;
+ }
+
+ /**
+ * Sets whether the node is an opennet peer.
+ *
+ * @param opennet
+ * <code>true</code> if the node is an opennet peer,
+ * <code>false</code> otherwise
+ */
+ public void setOpennet(boolean opennet) {
+ this.opennet = opennet;
+ }
+
+ /**
+ * Returns the name of the node. If the node is an opennet peer, it will not
+ * have a name!
+ *
+ * @return The name of the node, or <code>null</code> if the node is an
+ * opennet peer
+ */
+ public String getMyName() {
+ return name;
+ }
+
+ /**
+ * Sets the name of the peer.
+ *
+ * @param name
+ * The name of the peer
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the location of the node.
+ *
+ * @return The location of the node
+ */
+ public double getLocation() {
+ return location;
+ }
+
+ /**
+ * Sets the location of the node
+ *
+ * @param location
+ * The location of the node
+ */
+ public void setLocation(double location) {
+ this.location = location;
+ }
+
+ /**
+ * Returns the IP addresses and port numbers of the node.
+ *
+ * @return The IP addresses and port numbers of the node
+ */
+ public String getPhysicalUDP() {
+ return physicalUDP;
+ }
+
+ /**
+ * Sets the IP addresses and port numbers of the node.
+ *
+ * @param physicalUDP
+ * The IP addresses and port numbers of the node
+ */
+ public void setPhysicalUDP(String physicalUDP) {
+ this.physicalUDP = physicalUDP;
+ }
+
+ /**
+ * Returns the ARK of the node.
+ *
+ * @return The ARK of the node
+ */
+ public ARK getARK() {
+ return ark;
+ }
+
+ /**
+ * Sets the ARK of the node.
+ *
+ * @param ark
+ * The ARK of the node
+ */
+ public void setARK(ARK ark) {
+ this.ark = ark;
+ }
+
+ /**
+ * Returns the public DSA key of the node.
+ *
+ * @return The public DSA key of the node
+ */
+ public String getDSAPublicKey() {
+ return dsaPublicKey;
+ }
+
+ /**
+ * Sets the public DSA key of the node.
+ *
+ * @param dsaPublicKey
+ * The public DSA key of the node
+ */
+ public void setDSAPublicKey(String dsaPublicKey) {
+ this.dsaPublicKey = dsaPublicKey;
+ }
+
+ /**
+ * Returns the DSA group of the node.
+ *
+ * @return The DSA group of the node
+ */
+ public DSAGroup getDSAGroup() {
+ return dsaGroup;
+ }
+
+ /**
+ * Sets the DSA group of the node.
+ *
+ * @param dsaGroup
+ * The DSA group of the node
+ */
+ public void setDSAGroup(DSAGroup dsaGroup) {
+ this.dsaGroup = dsaGroup;
+ }
+
+ /**
+ * Returns the negotiation types supported by the node.
+ *
+ * @return The node’s supported negotiation types
+ */
+ public int[] getNegotiationTypes() {
+ return negotiationTypes;
+ }
+
+ /**
+ * Sets the negotiation types supported by the node.
+ *
+ * @param negotiationTypes
+ * The node’s supported negotiation types
+ */
+ public void setNegotiationTypes(int[] negotiationTypes) {
+ this.negotiationTypes = negotiationTypes;
+ }
+
+ /**
+ * Returns the version of the node.
+ *
+ * @return The version of the node
+ */
+ public Version getVersion() {
+ return version;
+ }
+
+ /**
+ * Sets the version of the node.
+ *
+ * @param version
+ * The version of the node
+ */
+ public void setVersion(Version version) {
+ this.version = version;
+ }
+
+ /**
+ * Returns the last good version of the node.
+ *
+ * @return The oldest version the node will connect to
+ */
+ public Version getLastGoodVersion() {
+ return lastGoodVersion;
+ }
+
+ /**
+ * Sets the last good version of the node.
+ *
+ * @param lastGoodVersion
+ * The oldest version the node will connect to
+ */
+ public void setLastGoodVersion(Version lastGoodVersion) {
+ this.lastGoodVersion = lastGoodVersion;
+ }
+
+ /**
+ * Returns whether the node is a testnet node.
+ *
+ * @return <code>true</code> if the node is a testnet node,
+ * <code>false</code> otherwise
+ */
+ public boolean isTestnet() {
+ return testnet;
+ }
+
+ /**
+ * Sets whether this node is a testnet node.
+ *
+ * @param testnet
+ * <code>true</code> if the node is a testnet node,
+ * <code>false</code> otherwise
+ */
+ public void setTestnet(boolean testnet) {
+ this.testnet = testnet;
+ }
+
+ /**
+ * Returns the signature of the noderef.
+ *
+ * @return The signature of the noderef
+ */
+ public String getSignature() {
+ return signature;
+ }
+
+ /**
+ * Sets the signature of the noderef.
+ *
+ * @param signature
+ * The signature of the noderef
+ */
+ public void setSignature(String signature) {
+ this.signature = signature;
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - Peer.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * The “Peer” reply by the node contains information about a peer.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class Peer extends BaseMessage {
+
+ /**
+ * Creates a new “Peer” reply from the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ Peer(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns a collection of fields as a node reference.
+ *
+ * @return The node reference contained within this message
+ */
+ public NodeRef getNodeRef() {
+ NodeRef nodeRef = new NodeRef();
+ nodeRef.setARK(getARK());
+ nodeRef.setDSAGroup(getDSAGroup());
+ nodeRef.setDSAPublicKey(getDSAPublicKey());
+ nodeRef.setIdentity(getIdentity());
+ nodeRef.setLastGoodVersion(getLastGoodVersion());
+ nodeRef.setLocation(getLocation());
+ nodeRef.setName(getMyName());
+ nodeRef.setNegotiationTypes(getNegotiationTypes());
+ nodeRef.setOpennet(isOpennet());
+ nodeRef.setPhysicalUDP(getPhysicalUDP());
+ nodeRef.setVersion(getVersion());
+ return nodeRef;
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the “physical.udp” line from the message. It contains all IP
+ * addresses and port numbers of the peer.
+ *
+ * @return The IP addresses and port numbers of the peer
+ */
+ public String getPhysicalUDP() {
+ return getField("physical.udp");
+ }
+
+ /**
+ * Returns whether the listed peer is an opennet peer.
+ *
+ * @return <code>true</code> if the peer is an opennet peer,
+ * <code>false</code> if the peer is a darknet peer
+ */
+ public boolean isOpennet() {
+ return Boolean.valueOf(getField("opennet"));
+ }
+
+ /**
+ * Returns whether this peer is a seed.
+ *
+ * @return <code>true</code> if the peer is a seed, <code>false</code>
+ * otherwise
+ */
+ public boolean isSeed() {
+ return Boolean.valueOf(getField("seed"));
+ }
+
+ /**
+ * Returns the “y” part of the peer’s public DSA key.
+ *
+ * @return The public DSA key
+ */
+ public String getDSAPublicKey() {
+ return getField("dsaPubKey.y");
+ }
+
+ /**
+ * Returns the DSA group of the peer.
+ *
+ * @return The DSA group of the peer
+ */
+ public DSAGroup getDSAGroup() {
+ return new DSAGroup(getField("dsaGroup.g"), getField("dsaGroup.p"), getField("dsaGroup.q"));
+ }
+
+ /**
+ * Returns the last good version of the peer, i.e. the oldest version the
+ * peer will connect to.
+ *
+ * @return The last good version of the peer
+ */
+ public Version getLastGoodVersion() {
+ return new Version(getField("lastGoodVersion"));
+ }
+
+ /**
+ * Returns the ARK of the peer.
+ *
+ * @return The ARK of the peer
+ */
+ public ARK getARK() {
+ return new ARK(getField("ark.pubURI"), getField("ark.number"));
+ }
+
+ /**
+ * Returns the identity of the peer.
+ *
+ * @return The identity of the peer
+ */
+ public String getIdentity() {
+ return getField("identity");
+ }
+
+ /**
+ * Returns the name of the peer. If the peer is not a darknet peer it will
+ * have no name.
+ *
+ * @return The name of the peer, or <code>null</code> if the peer is an
+ * opennet peer
+ */
+ public String getMyName() {
+ return getField("myName");
+ }
+
+ /**
+ * Returns the location of the peer.
+ *
+ * @return The location of the peer
+ * @throws NumberFormatException
+ * if the field can not be parsed
+ */
+ public double getLocation() throws NumberFormatException {
+ return Double.valueOf(getField("location"));
+ }
+
+ /**
+ * Returns whether the peer is a testnet node.
+ *
+ * @return <code>true</code> if the peer is a testnet node,
+ * <code>false</code> otherwise
+ */
+ public boolean isTestnet() {
+ return Boolean.valueOf("testnet");
+ }
+
+ /**
+ * Returns the version of the peer.
+ *
+ * @return The version of the peer
+ */
+ public Version getVersion() {
+ return new Version(getField("version"));
+ }
+
+ /**
+ * Returns the negotiation types the peer supports.
+ *
+ * @return The supported negotiation types
+ */
+ public int[] getNegotiationTypes() {
+ return FcpUtils.decodeMultiIntegerField(getField("auth.negTypes"));
+ }
+
+ /**
+ * Returns all volatile fields from the message.
+ *
+ * @return All volatile files
+ */
+ public Map<String, String> getVolatileFields() {
+ Map<String, String> volatileFields = new HashMap<String, String>();
+ for (Entry<String, String> field : getFields().entrySet()) {
+ if (field.getKey().startsWith("volatile.")) {
+ volatileFields.put(field.getKey(), field.getValue());
+ }
+ }
+ return Collections.unmodifiableMap(volatileFields);
+ }
+
+ /**
+ * Returns one of the volatile fields from the message. The given field name
+ * is prepended with “volatile.” so if you want to get the value of the
+ * field with the name “volatile.status” you only need to specify “status”.
+ *
+ * @param field
+ * The name of the field
+ * @return The value of the field, or <code>null</code> if there is no such
+ * field
+ */
+ public String getVolatile(String field) {
+ return getField("volatile." + field);
+ }
+
+ /**
+ * Returns all metadata fields from the message.
+ *
+ * @return All volatile files
+ */
+ public Map<String, String> getMetadataFields() {
+ Map<String, String> metadataFields = new HashMap<String, String>();
+ for (Entry<String, String> field : getFields().entrySet()) {
+ if (field.getKey().startsWith("metadata.")) {
+ metadataFields.put(field.getKey(), field.getValue());
+ }
+ }
+ return Collections.unmodifiableMap(metadataFields);
+ }
+
+ /**
+ * Returns one of the metadata fields from the message. The given field name
+ * is prepended with “metadata.” so if you want to get the value of the
+ * field with the name “metadata.timeLastRoutable” you only need to specify
+ * “timeLastRoutable”.
+ *
+ * @param field
+ * The name of the field
+ * @return The value of the field, or <code>null</code> if there is no such
+ * field
+ */
+ public String getMetadata(String field) {
+ return getField("metadata." + field);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PeerNote.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PeerNote” message contains a private note that has been entered for a
+ * darknet peer.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PeerNote extends BaseMessage {
+
+ /** The type for base64 encoded peer notes. */
+ public static final int TYPE_PRIVATE_PEER_NOTE = 1;
+
+ /**
+ * Creates a “PeerNote” message that wraps the recevied message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ PeerNote(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the node this note belongs to.
+ *
+ * @return The note’s node’s identifier
+ */
+ public String getNodeIdentifier() {
+ return getField("NodeIdentifier");
+ }
+
+ /**
+ * Returns the base64-encoded note text.
+ *
+ * @return The note text
+ */
+ public String getNoteText() {
+ return getField("NoteText");
+ }
+
+ /**
+ * Returns the type of the peer note.
+ *
+ * @return The type of the peer note, or <code>-1</code> if the type can not
+ * be parsed
+ */
+ public int getPeerNoteType() {
+ return FcpUtils.safeParseInt(getField("PeerNoteType"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PeerRemoved.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “PeerRemoved” message is sent by the node when a peer has been removed.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - Persistence.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Convenience class for persistence values.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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;
+
+}
--- /dev/null
+/*
+ * jFCPlib - PersistentGet.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PersistentGet” message is sent to the client to inform it about a
+ * persistent download, either in the client-local queue or in the global queue.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PersistentGet extends BaseMessage {
+
+ /**
+ * Creates a new “PersistentGet” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ PersistentGet(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the URI of the request.
+ *
+ * @return The URI of the request
+ */
+ public String getURI() {
+ return getField("URI");
+ }
+
+ /**
+ * Returns the verbosity of the request.
+ *
+ * @return The verbosity of the request
+ */
+ public Verbosity getVerbosity() {
+ return Verbosity.valueOf(getField("Verbosity"));
+ }
+
+ /**
+ * Returns the return type of the request.
+ *
+ * @return The return type of the request
+ */
+ public ReturnType getReturnType() {
+ try {
+ return ReturnType.valueOf(getField("ReturnType"));
+ } catch (IllegalArgumentException iae1) {
+ return ReturnType.unknown;
+ }
+ }
+
+ /**
+ * Returns the name of the file the data is downloaded to. This field will
+ * only be set if {@link #getReturnType()} is {@link ReturnType#disk}.
+ *
+ * @return The name of the file the data is downloaded to
+ */
+ public String getFilename() {
+ return getField("Filename");
+ }
+
+ /**
+ * Returns the name of the temporary file. This field will only be set if
+ * {@link #getReturnType()} is {@link ReturnType#disk}.
+ *
+ * @return The name of the temporary file
+ */
+ public String getTempFilename() {
+ return getField("TempFilename");
+ }
+
+ /**
+ * Returns the client token of the request.
+ *
+ * @return The client token of the request
+ */
+ public String getClientToken() {
+ return getField("ClientToken");
+ }
+
+ /**
+ * Returns the priority of the request.
+ *
+ * @return The priority of the request
+ */
+ public Priority getPriority() {
+ return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
+ }
+
+ /**
+ * Returns the persistence of the request.
+ *
+ * @return The persistence of the request, or {@link Persistence#unknown} if
+ * the persistence could not be parsed
+ */
+ public Persistence getPersistence() {
+ try {
+ return Persistence.valueOf(getField("Persistence"));
+ } catch (IllegalArgumentException iae1) {
+ return Persistence.unknown;
+ }
+ }
+
+ /**
+ * Returns whether this request is on the global queue or on the
+ * client-local queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> if the request is on the client-local queue
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+ /**
+ * Returns the maximum number of retries for a failed block.
+ *
+ * @return The maximum number of retries for a failed block, <code>-1</code>
+ * for endless retries, <code>-2</code> if the number could not be
+ * parsed
+ */
+ public int getMaxRetries() {
+ return FcpUtils.safeParseInt(getField("MaxRetries"), -2);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PersistentPut.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “PersistentPut” message notifies a client about a persistent
+ * {@link ClientPut} request.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PersistentPut extends BaseMessage {
+
+ /**
+ * Creates a new “PersistentPut” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ PersistentPut(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the client token of the request.
+ *
+ * @return The client token of the request
+ */
+ public String getClientToken() {
+ return getField("ClientToken");
+ }
+
+ /**
+ * Returns the data length of the request.
+ *
+ * @return The data length of the request, or <code>-1</code> if the length
+ * could not be parsed
+ */
+ public long getDataLength() {
+ return FcpUtils.safeParseLong(getField("DataLength"));
+ }
+
+ /**
+ * Returns whether the request is on the global queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> otherwise
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the maximum number of retries for failed blocks. When
+ * <code>-1</code> is returned each block is tried forever.
+ *
+ * @return The maximum number of retries for failed blocks, or
+ * <code>-1</code> for unlimited retries, or <code>-2</code> if the
+ * number of retries could not be parsed
+ */
+ public int getMaxRetries() {
+ return FcpUtils.safeParseInt(getField("MaxRetries"));
+ }
+
+ /**
+ * Returns the content type of the data.
+ *
+ * @return The content type
+ */
+ public String getMetadataContentType() {
+ return getField("Metadata.ContentType");
+ }
+
+ /**
+ * Returns the persistence of the request.
+ *
+ * @return The persistence of the request
+ */
+ public Persistence getPersistence() {
+ return Persistence.valueOf(getField("Persistence"));
+ }
+
+ /**
+ * Returns the priority of the request.
+ *
+ * @return The priority of the request, or {@link Priority#unknown} if the
+ * priority could not be parsed
+ */
+ public Priority getPriority() {
+ return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
+ }
+
+ /**
+ * Returns whether this request has started.
+ *
+ * @return <code>true</code> if the request has started, <code>false</code>
+ * otherwise
+ */
+ public boolean isStarted() {
+ return Boolean.valueOf(getField("Started"));
+ }
+
+ /**
+ * Returns the target filename of the request.
+ *
+ * @return The target filename of the request
+ */
+ public String getTargetFilename() {
+ return getField("TargetFilename");
+ }
+
+ /**
+ * Returns the upload source of the request.
+ *
+ * @return The upload source of the request
+ */
+ public UploadFrom getUploadFrom() {
+ return UploadFrom.valueOf(getField("UploadFrom"));
+ }
+
+ /**
+ * Returns the target URI of the request.
+ *
+ * @return The target URI of the request
+ */
+ public String getURI() {
+ return getField("URI");
+ }
+
+ /**
+ * Returns the verbosity of the request.
+ *
+ * @return The verbosity of the request
+ */
+ public Verbosity getVerbosity() {
+ return Verbosity.valueOf(getField("Verbosity"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PersistentPutDir.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “PersistentPutDir” is the response to a {@link ClientPutDiskDir} message.
+ * It is also sent as a possible response to a {@link ListPersistentRequests}
+ * message.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PersistentPutDir extends BaseMessage {
+
+ /**
+ * Creates a new “PersistentPutDir” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ PersistentPutDir(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the URI of the request.
+ *
+ * @return The URI of the request
+ */
+ public String getURI() {
+ return getField("URI");
+ }
+
+ /**
+ * Returns the verbosity of the request.
+ *
+ * @return The verbosity of the request
+ */
+ public Verbosity getVerbosity() {
+ return Verbosity.valueOf(getField("Verbosity"));
+ }
+
+ /**
+ * Returns the priority of the request.
+ *
+ * @return The priority of the request
+ */
+ public Priority getPriority() {
+ return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
+ }
+
+ /**
+ * Returns whether the request is on the global queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on the client-local queue
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+ /**
+ * Returns the maximum number of retries for failed blocks.
+ *
+ * @return The maximum number of retries, or <code>-1</code> for endless
+ * retries, or <code>-2</code> if the number could not be parsed
+ */
+ public int getMaxRetries() {
+ return FcpUtils.safeParseInt(getField("MaxRetries"), -2);
+ }
+
+ /**
+ * Returns the number of files in the request.
+ *
+ * @return The number of files in the request
+ */
+ public int getFileCount() {
+ int fileCount = -1;
+ while (getField("Files." + ++fileCount + ".UploadFrom") != null) {
+ /* do nothing. */
+ }
+ return fileCount;
+ }
+
+ /**
+ * Returns the name of the file at the given index. The index is counted
+ * from <code>0</code>.
+ *
+ * @param fileIndex
+ * The index of the file
+ * @return The name of the file at the given index
+ */
+ public String getFileName(int fileIndex) {
+ return getField("Files." + fileIndex + ".Name");
+ }
+
+ /**
+ * Returns the length of the file at the given index. The index is counted
+ * from <code>0</code>.
+ *
+ * @param fileIndex
+ * The index of the file
+ * @return The length of the file at the given index
+ */
+ public long getFileDataLength(int fileIndex) {
+ return FcpUtils.safeParseLong(getField("Files." + fileIndex + ".DataLength"));
+ }
+
+ /**
+ * Returns the upload source of the file at the given index. The index is
+ * counted from <code>0</code>.
+ *
+ * @param fileIndex
+ * The index of the file
+ * @return The upload source of the file at the given index
+ */
+ public UploadFrom getFileUploadFrom(int fileIndex) {
+ return UploadFrom.valueOf(getField("Files." + fileIndex + ".UploadFrom"));
+ }
+
+ /**
+ * Returns the content type of the file at the given index. The index is
+ * counted from <code>0</code>.
+ *
+ * @param fileIndex
+ * The index of the file
+ * @return The content type of the file at the given index
+ */
+ public String getFileMetadataContentType(int fileIndex) {
+ return getField("Files." + fileIndex + ".Metadata.ContentType");
+ }
+
+ /**
+ * Returns the filename of the file at the given index. This value is only
+ * returned if {@link #getFileUploadFrom(int)} is returning
+ * {@link UploadFrom#disk}. The index is counted from <code>0</code>.
+ *
+ * @param fileIndex
+ * The index of the file
+ * @return The filename of the file at the given index
+ */
+ public String getFileFilename(int fileIndex) {
+ return getField("Files." + fileIndex + ".Filename");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PersistentRequestModified.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PersistentRequestModified” message is a reply to
+ * {@link ModifyPersistentRequest}.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PersistentRequestModified extends BaseMessage {
+
+ /**
+ * Creates a new “PersistentRequestModified” message that wraps the received
+ * message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ PersistentRequestModified(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the changed request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns whether the request is on the global queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on a client-local queue
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+ /**
+ * Returns the client token, if it was changed.
+ *
+ * @return The new client token, or <code>null</code> if the client token
+ * was not changed
+ */
+ public String getClientToken() {
+ return getField("ClientToken");
+ }
+
+ /**
+ * Returns the priority of the request, if it was changed.
+ *
+ * @return The new priority of the request, or {@link Priority#unknown} if
+ * the priority was not changed
+ */
+ public Priority getPriority() {
+ return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PersistentRequestRemoved.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “PersistentRequestRemoved” message signals that a persistent request was
+ * removed from either the global or the client-local queue.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PersistentRequestRemoved extends BaseMessage {
+
+ /**
+ * Creates a new “PersistentRequestRemoved” message that wraps the received
+ * message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ PersistentRequestRemoved(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns whether the request was removed from the global queue.
+ *
+ * @return <code>true</code> if the request was removed from the global
+ * queue, <code>false</code> if it was removed from the client-local
+ * queue
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PluginInfo.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PluginInfo” message is a reply to the {@link GetPluginInfo} request.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PluginInfo extends BaseMessage {
+
+ /**
+ * Creates a new “PluginInfo” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ PluginInfo(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the name of the plugin.
+ *
+ * @return The name of the plugin
+ */
+ public String getPluginName() {
+ return getField("PluginName");
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the original URI of the plugin.
+ *
+ * @return The original URI of the plugin
+ */
+ public String getOriginalURI() {
+ return getField("OriginalUri");
+ }
+
+ /**
+ * Returns whether the plugin is started.
+ *
+ * @return <code>true</code> if the plugin is started, <code>false</code>
+ * otherwise
+ */
+ public boolean isStarted() {
+ return Boolean.valueOf("Started");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - Priority.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The priority classes used by the Freenet node.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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());
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ProtocolError.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “ProtocolError” message signals that something has gone really wrong.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ProtocolError extends BaseMessage {
+
+ /**
+ * Creates a new “ProtocolError” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ ProtocolError(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns whether the causing message had the “Global” flag set.
+ *
+ * @return <code>true</code> if the causing message had the “Global” flag
+ * set
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+ /**
+ * Returns the error code.
+ *
+ * @return The error code, or <code>-1</code> if the error code could not be
+ * parsed
+ */
+ public int getCode() {
+ return FcpUtils.safeParseInt(getField("Code"));
+ }
+
+ /**
+ * Returns the description of the error.
+ *
+ * @return The description of the error
+ */
+ public String getCodeDescription() {
+ return getField("CodeDescription");
+ }
+
+ /**
+ * Returns some extra description of the error.
+ *
+ * @return Extra description of the error, or <code>null</code> if there is
+ * none
+ */
+ public String getExtraDescription() {
+ return getField("ExtraDescription");
+ }
+
+ /**
+ * Returns whether the connection to the node can stay open.
+ *
+ * @return <code>true</code> when the connection has to be closed,
+ * <code>false</code> otherwise
+ */
+ public boolean isFatal() {
+ return Boolean.valueOf(getField("Fatal"));
+ }
+
+ /**
+ * The identifier of the causing request, if any.
+ *
+ * @return The identifier of the causing request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - GetFailed.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * The “PutFailed” message signals the client that a {@link ClientPut} request
+ * has failed. This also means that no further progress messages for that
+ * request will be sent.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PutFailed extends BaseMessage {
+
+ /**
+ * Creates a new “PutFailed” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ PutFailed(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the code of the error.
+ *
+ * @return The code of the error, or <code>-1</code> if the error code could
+ * not be parsed
+ */
+ public int getCode() {
+ return FcpUtils.safeParseInt(getField("Code"));
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns whether the request is on the global queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on the client-local queue
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+ /**
+ * Returns the description of the error code.
+ *
+ * @return The description of the error code
+ */
+ public String getCodeDescription() {
+ return getField("CodeDescription");
+ }
+
+ /**
+ * Returns the extra description of the error.
+ *
+ * @return The extra description of the error
+ */
+ public String getExtraDescription() {
+ return getField("ExtraDescription");
+ }
+
+ /**
+ * Returns the short description of the error.
+ *
+ * @return The short description of the error
+ */
+ public String getShortCodeDescription() {
+ return getField("ShortCodeDescription");
+ }
+
+ /**
+ * Returns the expected URI of the request.
+ *
+ * @return The expected URI
+ */
+ public String getExpectedURI() {
+ return getField("ExpectedURI");
+ }
+
+ /**
+ * Returns whether the request failed fatally. If a request fails fatally it
+ * can never complete, even with inifinite retries.
+ *
+ * @return <code>true</code> if the request failed fatally,
+ * <code>false</code> otherwise
+ */
+ public boolean isFatal() {
+ return Boolean.valueOf(getField("Fatal"));
+ }
+
+ /**
+ * Returns a list of complex error codes with the message. Use
+ * {@link #getComplexErrorDescription(int)} and
+ * {@link #getComplexErrorCount(int)} to get details.
+ *
+ * @return A list of complex error codes
+ */
+ public int[] getComplexErrorCodes() {
+ Map<String, String> allFields = getFields();
+ List<Integer> errorCodeList = new ArrayList<Integer>();
+ for (Entry<String, String> field : allFields.entrySet()) {
+ String fieldKey = field.getKey();
+ if (fieldKey.startsWith("Errors.")) {
+ int nextDot = fieldKey.indexOf('.', 7);
+ if (nextDot > -1) {
+ int errorCode = FcpUtils.safeParseInt(fieldKey.substring(7, nextDot));
+ if (errorCode != -1) {
+ errorCodeList.add(errorCode);
+ }
+ }
+ }
+ }
+ int[] errorCodes = new int[errorCodeList.size()];
+ int errorIndex = 0;
+ for (int errorCode : errorCodeList) {
+ errorCodes[errorIndex++] = errorCode;
+ }
+ return errorCodes;
+ }
+
+ /**
+ * Returns the description of the complex error. You should only hand it
+ * error codes you got from {@link #getComplexErrorCodes()}!
+ *
+ * @param errorCode
+ * The error code
+ * @return The description of the complex error
+ */
+ public String getComplexErrorDescription(int errorCode) {
+ return getField("Errors." + errorCode + ".Description");
+ }
+
+ /**
+ * Returns the count of the complex error. You should only hand it error
+ * codes you got from {@link #getComplexErrorCodes()}!
+ *
+ * @param errorCode
+ * The error code
+ * @return The count of the complex error, or <code>-1</code> if the count
+ * could not be parsed
+ */
+ public int getComplexErrorCount(int errorCode) {
+ return FcpUtils.safeParseInt(getField("Errors." + errorCode + ".Count"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PutFetchable.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PutFetchable” message informs a client that a {@link ClientPut} request
+ * has progressed far enough that the resulting final URI might already be
+ * fetchable.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PutFetchable extends BaseMessage {
+
+ /**
+ * Creates a new “PutFetchable” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ PutFetchable(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns whether the request is on the global queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on the client-local queue
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+ /**
+ * Returns the URI of the request.
+ *
+ * @return The URI of the request
+ */
+ public String getURI() {
+ return getField("URI");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PutSuccessful.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “PutSuccessful” message informs a client about a successfully finished
+ * {@link ClientPut} (or similar) request.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PutSuccessful extends BaseMessage {
+
+ /**
+ * Creates a new “PutSuccessful” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ PutSuccessful(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns whether the request is on the global queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on the client-local queue
+ */
+ public boolean isGlobal() {
+ return Boolean.valueOf(getField("Global"));
+ }
+
+ /**
+ * Returns the final URI of the {@link ClientPut} request.
+ *
+ * @return The final URI of the request
+ */
+ public String getURI() {
+ return getField("URI");
+ }
+
+ /**
+ * Returns the time the insert started.
+ *
+ * @return The time the insert started (in milliseconds since Jan 1, 1970
+ * UTC), or <code>-1</code> if the time could not be parsed
+ */
+ public long getStartupTime() {
+ return FcpUtils.safeParseLong(getField("StartupTime"));
+ }
+
+ /**
+ * Returns the time the insert completed.
+ *
+ * @return The time the insert completed (in milliseconds since Jan 1, 1970
+ * UTC), or <code>-1</code> if the time could not be parsed
+ */
+ public long getCompletionTime() {
+ return FcpUtils.safeParseLong(getField("CompletionTime"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ReceivedBookmarkFeed.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Implementation of the “ReceivedBookmarkFeed” FCP message. This message
+ * notifies an FCP client that an update for a bookmark has been found.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class ReceivedBookmarkFeed extends BaseMessage {
+
+ /**
+ * Creates a new “ReceivedBookmarkFeed” message.
+ *
+ * @param fcpMessage
+ * The FCP message to get the fields from
+ */
+ public ReceivedBookmarkFeed(FcpMessage fcpMessage) {
+ super(fcpMessage);
+ }
+
+ /**
+ * Returns the name of the bookmark.
+ *
+ * @return The bookmark’s name
+ */
+ public String getBookmarkName() {
+ return getField("Name");
+ }
+
+ /**
+ * Returns the URI of the updated bookmark.
+ *
+ * @return The bookmark’s URI
+ */
+ public String getURI() {
+ return getField("URI");
+ }
+
+ /**
+ * Returns whether the bookmark has an active link image.
+ *
+ * @return {@code true} if the bookmark has an active link image, {@code
+ * false} otherwise
+ */
+ public boolean hasActiveLink() {
+ return Boolean.parseBoolean(getField("HasAnActiveLink"));
+ }
+
+ /**
+ * Returns the description of the bookmark. Note that the description may be
+ * {@code null} and if it is not, it is base64-encoded!
+ *
+ * @return The bookmark’s description, or {@code null} if the bookmark has
+ * no description
+ */
+ public String getDescription() {
+ return getField("Description");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - RemovePeer.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “RemovePeer” command removes a peer.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - RemovePersistentRequest.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “RemovePersistentRequest” message tells the node to remove a persistent
+ * request, cancelling it first (resulting in a {@link GetFailed} or
+ * {@link PutFailed} message), if necessary.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class RemovePersistentRequest extends FcpMessage {
+
+ /**
+ * Creates a new “RemovePersistentRequest” message.
+ *
+ * @param identifier
+ * The identifier of the request
+ */
+ public RemovePersistentRequest(String identifier) {
+ super("RemovePersistentRequest");
+ setField("Identifier", identifier);
+ }
+
+ /**
+ * Sets whether the request is on the global queue.
+ *
+ * @param global
+ * <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on the client-local queue
+ */
+ public void setGlobal(boolean global) {
+ setField("Global", String.valueOf(global));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - ReturnType.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The different return types for {@link ClientGet} requests.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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;
+
+}
--- /dev/null
+/*
+ * jFCPlib - SSKKeypair.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * An “SSKKeypair” message that is sent as a response to a {@link GenerateSSK}
+ * message.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - SendBookmarkFeed.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “SendBookmarkFeed” command sends a bookmark to a peer.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class SendBookmarkFeed extends AbstractSendFeedMessage {
+
+ /**
+ * Creates a new “SendBookmarkFeed” command.
+ *
+ * @param identifier
+ * The identifier of the request
+ * @param nodeIdentifier
+ * The identifier of the peer node
+ * @param name
+ * The name of the bookmark
+ * @param uri
+ * The URI of the bookmark
+ * @param description
+ * The description of the bookmark (may be {@code null})
+ * @param hasActiveLink
+ * {@code true} if the bookmark has an activelink image, {@code
+ * false} otherwise
+ */
+ public SendBookmarkFeed(String identifier, String nodeIdentifier, String name, String uri, String description, boolean hasActiveLink) {
+ super("SendBookmarkFeed", identifier, nodeIdentifier);
+ setField("Name", name);
+ setField("URI", uri);
+ setField("Description", description);
+ setField("HasActiveLink", String.valueOf(hasActiveLink));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - SendDownloadFeed.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “SendDownloadFeed” command sends information about a download to a peer
+ * node.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class SendDownloadFeed extends AbstractSendFeedMessage {
+
+ /**
+ * Creates a new “SendDownloadFeed” to a peer node.
+ *
+ * @param identifier
+ * The identifier of the request
+ * @param nodeIdentifier
+ * The identifier of the peer node
+ * @param uri
+ * The URI of the download to send
+ * @param description
+ * The description of the download (may be {@code null})
+ */
+ public SendDownloadFeed(String identifier, String nodeIdentifier, String uri, String description) {
+ super("SendDownloadFeed", identifier, nodeIdentifier);
+ setField("URI", uri);
+ setField("Description", description);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - SendTextFeed.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “SendTextFeed” command sends an arbitrary text to a peer node.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class SendTextFeed extends AbstractSendFeedMessage {
+
+ /**
+ * Creates a new “SendTextFeed” command.
+ *
+ * @param identifier
+ * The identifier of the request
+ * @param nodeIdentifier
+ * The identifier of the peer node
+ * @param text
+ * The text to send
+ */
+ public SendTextFeed(String identifier, String nodeIdentifier, String text) {
+ super("SendTextFeed", identifier, nodeIdentifier);
+ setField("Text", text);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - SentFeed.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “SentFeed” message signals that a feed was successfully sent to a peer.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class SentFeed extends BaseMessage {
+
+ /**
+ * Creates a new “SentFeed” message from the given FCP message.
+ *
+ * @param fcpMessage
+ * The FCP message containing the “SentFeed” message
+ */
+ public SentFeed(FcpMessage fcpMessage) {
+ super(fcpMessage);
+ }
+
+ /**
+ * Returns the identifier of the sent feed. The identifier of this message
+ * matches the identifier that was given when a {@link SendBookmarkFeed},
+ * {@link SendDownloadFeed}, or {@link SendTextFeed} command was created.
+ *
+ * @return The send feed’s identifier
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the node status of the peer. The node status is definied in
+ * {@code freenet.node.PeerManager}.
+ * <p>
+ * <ol start="1">
+ * <li>Connected</li>
+ * <li>Backed off</li>
+ * <li>Version too new</li>
+ * <li>Version too old</li>
+ * <li>Disconnected</li>
+ * <li>Never connected</li>
+ * <li>Disabled</li>
+ * <li>Bursting</li>
+ * <li>Listening</li>
+ * <li>Listening only</li>
+ * <li>Clock problem</li>
+ * <li>Connection error</li>
+ * <li>Disconnecting</li>
+ * <li>Routing disabled</li>
+ * </ol>
+ *
+ * @return The node’s status
+ */
+ public int getNodeStatus() {
+ return FcpUtils.safeParseInt(getField("NodeStatus"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - Shutdown.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Command that shuts down the node.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class Shutdown extends FcpMessage {
+
+ /**
+ * Creates a new “Shutdown” message.
+ */
+ public Shutdown() {
+ super("Shutdown");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - SimpleProgress.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “SimpleProgress” message tells the client about the progress of a
+ * {@link ClientGet} or {@link ClientPut} operation.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class SimpleProgress extends BaseMessage {
+
+ /**
+ * Creates a new “SimpleProgress” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ SimpleProgress(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the total number of blocks. This number may increase as long as
+ * {@link #isFinalizedTotal()} returns <code>false</code>.
+ *
+ * @return The total number of blocks
+ */
+ public int getTotal() {
+ return FcpUtils.safeParseInt(getField("Total"));
+ }
+
+ /**
+ * Returns the number of blocks that are required to completet the request.
+ * This number might actually be lower than {@link #getTotal} because of
+ * redundancy information. This number may also increase as long as
+ * {@link #isFinalizedTotal()} returns <code>false</code>.
+ *
+ * @return The number of required blocks
+ */
+ public int getRequired() {
+ return FcpUtils.safeParseInt(getField("Required"));
+ }
+
+ /**
+ * Returns the number of blocks that have failed and run out of retries.
+ *
+ * @return The number of failed blocks
+ */
+ public int getFailed() {
+ return FcpUtils.safeParseInt(getField("Failed"));
+ }
+
+ /**
+ * Returns the number of fatally failed blocks. A block that failed fatally
+ * can never be completed, even with infinite retries.
+ *
+ * @return The number of fatally failed blocks
+ */
+ public int getFatallyFailed() {
+ return FcpUtils.safeParseInt(getField("FatallyFailed"));
+ }
+
+ /**
+ * Returns the number of blocks that have been successfully processed.
+ *
+ * @return The number of succeeded blocks
+ */
+ public int getSucceeded() {
+ return FcpUtils.safeParseInt(getField("Succeeded"));
+ }
+
+ /**
+ * Returns whether the total number of blocks (see {@link #getTotal()} has
+ * been finalized. Once the total number of blocks has been finalized for a
+ * request it will not change any more, and this method of every further
+ * SimpleProgress message will always return <code>true</code>.
+ *
+ * @return <code>true</code> if the number of total blocks has been
+ * finalized, <code>false</code> otherwise
+ */
+ public boolean isFinalizedTotal() {
+ return Boolean.valueOf(getField("FinalizedTotal"));
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - StartedCompression.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “StartedCompression” message signals the client the compressing for a
+ * request has started.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class StartedCompression extends BaseMessage {
+
+ /**
+ * Creates a new “StartedCompression” message that wraps the received
+ * message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ StartedCompression(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the number of the codec that is used for compression.
+ *
+ * @return The codec used for the compression, or <code>-1</code> if the
+ * codec could not be parsed
+ */
+ public int getCodec() {
+ return FcpUtils.safeParseInt(getField("Codec"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - SubscribeFeeds.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “SubscribeFeeds” command tells the node that the client is interested in
+ * receiving the feeds sent by peer nodes.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class SubscribeFeeds extends FcpMessage {
+
+ /**
+ * Creates a new “SubscribeFeeds” command.
+ *
+ * @param identifier
+ * The identifier of the request
+ */
+ public SubscribeFeeds(String identifier) {
+ super("SubscribeFeeds");
+ setField("Identifier", identifier);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - SubscribeUSK.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * With a “SubscribeUSK” a client requests to be notified if the edition number
+ * of a USK changes.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class SubscribeUSK extends FcpMessage {
+
+ /**
+ * Creates a new “SubscribeUSK” message.
+ *
+ * @param uri
+ * The URI to watch for changes
+ * @param identifier
+ * The identifier of the request
+ */
+ public SubscribeUSK(String uri, String identifier) {
+ super("SubscribeUSK");
+ setField("URI", uri);
+ setField("Identifier", identifier);
+ }
+
+ /**
+ * Sets whether updates for the USK are actively searched.
+ *
+ * @param active
+ * <code>true</code> to actively search for newer editions,
+ * <code>false</code> to only watch for newer editions that are
+ * found from other requests
+ */
+ public void setActive(boolean active) {
+ setField("DontPoll", String.valueOf(!active));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - SubscribedUSKUpdate.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “SubscribedUSKUpdate” message is sent each time a new edition of a USK that
+ * was previously subscribed to with {@link SubscribeUSK} was found. Note that
+ * if the new edition that was found is several editions ahead of the currently
+ * last known edition, you will received a SubscribedUSKUpdate for each edition
+ * inbetween as welL!
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - TestDDAComplete.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “TestDDAComplete” message signals that the node has finished checking
+ * your read and write access to a certain directory.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class TestDDAComplete extends BaseMessage {
+
+ /**
+ * Creates a new “TestDDAComplete” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ TestDDAComplete(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the directory the authorization is given for.
+ *
+ * @return The directory that was tested for read and/or write access
+ */
+ public String getDirectory() {
+ return getField("Directory");
+ }
+
+ /**
+ * Returns whether read access to the directory is allowed.
+ *
+ * @return <code>true</code> if the client is allowed to read from that
+ * directory, <code>false</code> otherwise
+ */
+ public boolean isReadDirectoryAllowed() {
+ return Boolean.valueOf(getField("ReadDirectoryAllowed"));
+ }
+
+ /**
+ * Returns whether write access to the directory is allowed.
+ *
+ * @return <code>true</code> if the client is allowed to write into that
+ * directory, <code>false</code> otherwise
+ */
+ public boolean isWriteDirectoryAllowed() {
+ return Boolean.valueOf(getField("WriteDirectoryAllowed"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - TestDDAReply.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “TestDDAReply” is sent as a response to {@link TestDDARequest}. If you
+ * specified that you wanted to read files from that directory
+ * {@link #getReadFilename()} will give you a filename. Similarly, if you
+ * specified that you want to write in the directory {@link #getWriteFilename()}
+ * will give you a filename to write {@link #getContentToWrite()} to.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - TestDDARequest.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “TestDDARequest” initiates a DDA test sequence.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class TestDDARequest extends FcpMessage {
+
+ /**
+ * Creates a new “TestDDARequest” command that initiates a DDA test.
+ *
+ * @param directory
+ * The directory you want to access files in
+ * @param wantReadDirectory
+ * <code>true</code> if you want to read files from the directory
+ * @param wantWriteDirectory
+ * <code>true</code> if you want to write files to the directory
+ */
+ public TestDDARequest(String directory, boolean wantReadDirectory, boolean wantWriteDirectory) {
+ super("TestDDARequest");
+ setField("Directory", directory);
+ setField("WantReadDirectory", String.valueOf(wantReadDirectory));
+ setField("WantWriteDirectory", String.valueOf(wantWriteDirectory));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - TestDDAResponse.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * A “TestDDAResponse” is sent to let the node know that either created a file
+ * with the content from {@link TestDDAReply#getContentToWrite()} or that you
+ * read the content of the file given by {@link TestDDAReply#getReadFilename()}.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class TestDDAResponse extends FcpMessage {
+
+ /**
+ * Creates a new “TestDDAResponse” message that signals that you created the
+ * file given by {@link TestDDAReply#getWriteFilename()} and wrote the
+ * contents given by {@link TestDDAReply#getContentToWrite()} to it.
+ *
+ * @param directory
+ * The directory from the {@link TestDDARequest} command
+ */
+ public TestDDAResponse(String directory) {
+ this(directory, null);
+ }
+
+ /**
+ * Creates a new “TestDDAResponse” message that signals that you created the
+ * file given by {@link TestDDAReply#getWriteFilename()} with the contents
+ * given by {@link TestDDAReply#getContentToWrite()} to it (when you
+ * specified that you want to write to the directory) and/or that you read
+ * the file given by {@link TestDDAReply#getReadFilename()} (when you
+ * specified you wanted to read the directory).
+ *
+ * @param directory
+ * The directory from the {@link TestDDARequest} command
+ * @param readContent
+ * The read content, or <code>null</code> if you did not request
+ * read access
+ */
+ public TestDDAResponse(String directory, String readContent) {
+ super("TestDDAResponse");
+ if (readContent != null) {
+ setField("ReadContent", readContent);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - URIGenerated.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “URIGenerated” message signals the client that an URI was generated for a
+ * {@link ClientPut} (or {@link ClientPutDiskDir} or {@link ClientPutComplexDir}
+ * ) request.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class URIGenerated extends BaseMessage {
+
+ /**
+ * Creates a new “URIGenerated” message that wraps the received message.
+ *
+ * @param receivedMessage
+ * The received message
+ */
+ URIGenerated(FcpMessage receivedMessage) {
+ super(receivedMessage);
+ }
+
+ /**
+ * Returns the identifier of the request that generated an URI.
+ *
+ * @return The identifier of the request
+ */
+ public String getIdentifier() {
+ return getField("Identifier");
+ }
+
+ /**
+ * Returns the URI that was generated by the request.
+ *
+ * @return The URI that was generated by the request
+ */
+ public String getURI() {
+ return getField("URI");
+ }
+
+ /**
+ * Returns whether the request that generated the URI is on the global queue
+ * or on the client-local queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> if it is on the client-local queue
+ */
+ public boolean isGlobal() {
+ return Boolean.parseBoolean(getField("Global"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - UnknownNodeIdentifier.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “UnknownNodeIdentifier” message signals the client that the node
+ * identifier given in a command like {@link ListPeer} is unknown.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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");
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - UnknownPeerNoteType.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The ”UnknownPeerNoteType” message signals the client that the type of peer
+ * note used in a previous {@link ModifyPeerNote} is unknown.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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"));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - UploadFrom.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Enumeration for the different values for the “UploadFrom” field in
+ * {@link ClientPut} and {@link ClientGet} requests.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+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;
+
+}
--- /dev/null
+/*
+ * jFCPlib - Verbosity.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * Convenicence class for verbosity handling. This might come in handy with the
+ * {@link ClientPut} and {@link ClientGet} requests. The verbosity is a bit-mask
+ * that can be composed of several bits. {@link #PROGRESS} and
+ * {@link #COMPRESSION} are single bits in that mask and can be combined into a
+ * new verbosity using {@link #add(Verbosity)}.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class Verbosity {
+
+ /** Constant for no verbosity at all. */
+ public static final Verbosity NONE = new Verbosity(0);
+
+ /** Constant for progress message verbosity. */
+ public static final Verbosity PROGRESS = new Verbosity(1);
+
+ /** Constant for compression message verbosity. */
+ public static final Verbosity COMPRESSION = new Verbosity(512);
+
+ /** Constant for all events. */
+ public static final Verbosity ALL = new Verbosity(-1);
+
+ /** The verbosity level. */
+ private final int level;
+
+ /**
+ * Creates a new verbosity with the given level.
+ *
+ * @param level
+ * The verbosity level
+ */
+ private Verbosity(int level) {
+ this.level = level;
+ }
+
+ /**
+ * Adds the given verbosity to this verbosity and returns a verbosity with
+ * the new value. The value of this verbosity is not changed.
+ *
+ * @param verbosity
+ * The verbosity to add to this verbosity
+ * @return The verbosity with the new level.
+ */
+ public Verbosity add(Verbosity verbosity) {
+ return new Verbosity(level | verbosity.level);
+ }
+
+ /**
+ * Checks whether this Verbosity contains all bits of the given Verbosity.
+ *
+ * @param verbosity
+ * The verbosity to check for in this Verbosity
+ * @return <code>true</code> if and only if all set bits in the given
+ * Verbosity are also set in this Verbosity
+ */
+ public boolean contains(Verbosity verbosity) {
+ return (level & verbosity.level) == verbosity.level;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return String.valueOf(level);
+ }
+
+ /**
+ * Parses the given string and creates a Verbosity with the given level.
+ *
+ * @param s
+ * The string to parse
+ * @return The parsed verbosity, or {@link #NONE} if the string could not be
+ * parsed
+ */
+ public static Verbosity valueOf(String s) {
+ try {
+ return new Verbosity(Integer.valueOf(s));
+ } catch (NumberFormatException nfe1) {
+ return NONE;
+ }
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - Version.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.util.StringTokenizer;
+
+/**
+ * Container for the “lastGoodVersion” field.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class Version {
+
+ /** The name of the node implementation. */
+ private final String nodeName;
+
+ /** The tree version of the node. */
+ private final String treeVersion;
+
+ /** The protocol version of the node. */
+ private final String protocolVersion;
+
+ /** The build number of the node. */
+ private final int buildNumber;
+
+ /**
+ * Creates a new Version from the given string. The string consists of the
+ * four required fields node name, tree version, protocol version, and build
+ * number, separated by a comma.
+ *
+ * @param version
+ * The version string
+ * @throws NullPointerException
+ * if <code>version</code> is <code>null</code>
+ * @throws IllegalArgumentException
+ * if <code>version</code> is not in the right format
+ */
+ public Version(String version) {
+ if (version == null) {
+ throw new NullPointerException("version must not be null");
+ }
+ StringTokenizer versionTokens = new StringTokenizer(version, ",");
+ if (versionTokens.countTokens() != 4) {
+ throw new IllegalArgumentException("version must consist of four fields");
+ }
+ this.nodeName = versionTokens.nextToken();
+ this.treeVersion = versionTokens.nextToken();
+ this.protocolVersion = versionTokens.nextToken();
+ try {
+ this.buildNumber = Integer.valueOf(versionTokens.nextToken());
+ } catch (NumberFormatException nfe1) {
+ throw new IllegalArgumentException("last part of version must be numeric", nfe1);
+ }
+ }
+
+ /**
+ * Creates a new Version from the given parts.
+ *
+ * @param nodeName
+ * The name of the node implementation
+ * @param treeVersion
+ * The tree version
+ * @param protocolVersion
+ * The protocol version
+ * @param buildNumber
+ * The build number of the node
+ */
+ public Version(String nodeName, String treeVersion, String protocolVersion, int buildNumber) {
+ this.nodeName = nodeName;
+ this.treeVersion = treeVersion;
+ this.protocolVersion = protocolVersion;
+ this.buildNumber = buildNumber;
+ }
+
+ /**
+ * Returns the name of the node implementation.
+ *
+ * @return The node name
+ */
+ public String getNodeName() {
+ return nodeName;
+ }
+
+ /**
+ * The tree version of the node.
+ *
+ * @return The tree version of the node
+ */
+ public String getTreeVersion() {
+ return treeVersion;
+ }
+
+ /**
+ * The protocol version of the node
+ *
+ * @return The protocol version of the node
+ */
+ public String getProtocolVersion() {
+ return protocolVersion;
+ }
+
+ /**
+ * The build number of the node.
+ *
+ * @return The build number of the node
+ */
+ public int getBuildNumber() {
+ return buildNumber;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return nodeName + "," + treeVersion + "," + protocolVersion + "," + buildNumber;
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - WatchGlobal.java - Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+/**
+ * The “WatchGlobal” messages enables clients to watch the global queue in
+ * addition to the client-local queue.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class WatchGlobal extends FcpMessage {
+
+ /**
+ * Enables or disables watching the global queue.
+ *
+ * @param enabled
+ * <code>true</code> to watch the global queue and the
+ * client-local queue, <code>false</code> to watch only the
+ * client-local queue
+ */
+ public WatchGlobal(boolean enabled) {
+ this(enabled, Verbosity.ALL);
+ }
+
+ /**
+ * Enables or disables watching the global queue, optionally masking out
+ * certain events.
+ *
+ * @param enabled
+ * <code>true</code> to watch the global queue and the
+ * client-local queue, <code>false</code> to watch only the
+ * client-local queue
+ * @param verbosityMask
+ * A verbosity mask that determines which events are received
+ */
+ public WatchGlobal(boolean enabled, Verbosity verbosityMask) {
+ super("WatchGlobal");
+ setField("Enabled", String.valueOf(enabled));
+ setField("VerbosityMask", String.valueOf(verbosityMask));
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpClient.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.CountDownLatch;
+
+import net.pterodactylus.fcp.AddPeer;
+import net.pterodactylus.fcp.ClientHello;
+import net.pterodactylus.fcp.CloseConnectionDuplicateClientName;
+import net.pterodactylus.fcp.DataFound;
+import net.pterodactylus.fcp.EndListPeerNotes;
+import net.pterodactylus.fcp.EndListPeers;
+import net.pterodactylus.fcp.EndListPersistentRequests;
+import net.pterodactylus.fcp.FCPPluginMessage;
+import net.pterodactylus.fcp.FCPPluginReply;
+import net.pterodactylus.fcp.FcpAdapter;
+import net.pterodactylus.fcp.FcpConnection;
+import net.pterodactylus.fcp.FcpListener;
+import net.pterodactylus.fcp.GenerateSSK;
+import net.pterodactylus.fcp.GetFailed;
+import net.pterodactylus.fcp.GetNode;
+import net.pterodactylus.fcp.ListPeerNotes;
+import net.pterodactylus.fcp.ListPeers;
+import net.pterodactylus.fcp.ListPersistentRequests;
+import net.pterodactylus.fcp.ModifyPeer;
+import net.pterodactylus.fcp.ModifyPeerNote;
+import net.pterodactylus.fcp.NodeData;
+import net.pterodactylus.fcp.NodeHello;
+import net.pterodactylus.fcp.NodeRef;
+import net.pterodactylus.fcp.Peer;
+import net.pterodactylus.fcp.PeerNote;
+import net.pterodactylus.fcp.PeerRemoved;
+import net.pterodactylus.fcp.PersistentGet;
+import net.pterodactylus.fcp.PersistentPut;
+import net.pterodactylus.fcp.ProtocolError;
+import net.pterodactylus.fcp.RemovePeer;
+import net.pterodactylus.fcp.SSKKeypair;
+import net.pterodactylus.fcp.SimpleProgress;
+import net.pterodactylus.fcp.WatchGlobal;
+import net.pterodactylus.util.filter.Filter;
+import net.pterodactylus.util.filter.Filters;
+import net.pterodactylus.util.thread.ObjectWrapper;
+
+/**
+ * High-level FCP client that hides the details of the underlying FCP
+ * implementation.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class FcpClient {
+
+ /** Object used for synchronization. */
+ private final Object syncObject = new Object();
+
+ /** Listener management. */
+ private final FcpClientListenerManager fcpClientListenerManager = new FcpClientListenerManager(this);
+
+ /** The name of this client. */
+ private final String name;
+
+ /** The underlying FCP connection. */
+ private final FcpConnection fcpConnection;
+
+ /** Whether the client is currently connected. */
+ private volatile boolean connected;
+
+ /**
+ * Creates an FCP client with the given name.
+ *
+ * @param name
+ * The name of the FCP client
+ * @throws UnknownHostException
+ * if the hostname “localhost” is unknown
+ */
+ public FcpClient(String name) throws UnknownHostException {
+ this(name, "localhost");
+ }
+
+ /**
+ * Creates an FCP client.
+ *
+ * @param name
+ * The name of the FCP client
+ * @param hostname
+ * The hostname of the Freenet node
+ * @throws UnknownHostException
+ * if the given hostname can not be resolved
+ */
+ public FcpClient(String name, String hostname) throws UnknownHostException {
+ this(name, hostname, FcpConnection.DEFAULT_PORT);
+ }
+
+ /**
+ * Creates an FCP client.
+ *
+ * @param name
+ * The name of the FCP client
+ * @param hostname
+ * The hostname of the Freenet node
+ * @param port
+ * The Freenet node’s FCP port
+ * @throws UnknownHostException
+ * if the given hostname can not be resolved
+ */
+ public FcpClient(String name, String hostname, int port) throws UnknownHostException {
+ this(name, InetAddress.getByName(hostname), port);
+ }
+
+ /**
+ * Creates an FCP client.
+ *
+ * @param name
+ * The name of the FCP client
+ * @param host
+ * The host address of the Freenet node
+ */
+ public FcpClient(String name, InetAddress host) {
+ this(name, host, FcpConnection.DEFAULT_PORT);
+ }
+
+ /**
+ * Creates an FCP client.
+ *
+ * @param name
+ * The name of the FCP client
+ * @param host
+ * The host address of the Freenet node
+ * @param port
+ * The Freenet node’s FCP port
+ */
+ public FcpClient(String name, InetAddress host, int port) {
+ this.name = name;
+ fcpConnection = new FcpConnection(host, port);
+ fcpConnection.addFcpListener(new FcpAdapter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
+ connected = false;
+ fcpClientListenerManager.fireFcpClientDisconnected();
+ }
+ });
+ }
+
+ //
+ // LISTENER MANAGEMENT
+ //
+
+ /**
+ * Adds an FCP listener to the underlying connection.
+ *
+ * @param fcpListener
+ * The FCP listener to add
+ */
+ public void addFcpListener(FcpListener fcpListener) {
+ fcpConnection.addFcpListener(fcpListener);
+ }
+
+ /**
+ * Removes an FCP listener from the underlying connection.
+ *
+ * @param fcpListener
+ * The FCP listener to remove
+ */
+ public void removeFcpListener(FcpListener fcpListener) {
+ fcpConnection.removeFcpListener(fcpListener);
+ }
+
+ /**
+ * Adds an FCP client listener to the list of registered listeners.
+ *
+ * @param fcpClientListener
+ * The FCP client listener to add
+ */
+ public void addFcpClientListener(FcpClientListener fcpClientListener) {
+ fcpClientListenerManager.addListener(fcpClientListener);
+ }
+
+ /**
+ * Removes an FCP client listener from the list of registered listeners.
+ *
+ * @param fcpClientListener
+ * The FCP client listener to remove
+ */
+ public void removeFcpClientListener(FcpClientListener fcpClientListener) {
+ fcpClientListenerManager.removeListener(fcpClientListener);
+ }
+
+ //
+ // ACTIONS
+ //
+
+ /**
+ * Connects the FCP client.
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void connect() throws IOException, FcpException {
+ checkConnected(false);
+ connected = true;
+ new ExtendedFcpAdapter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ fcpConnection.connect();
+ ClientHello clientHello = new ClientHello(name);
+ fcpConnection.sendMessage(clientHello);
+ WatchGlobal watchGlobal = new WatchGlobal(true);
+ fcpConnection.sendMessage(watchGlobal);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) {
+ completionLatch.countDown();
+ }
+ }.execute();
+ }
+
+ /**
+ * Disconnects the FCP client.
+ */
+ public void disconnect() {
+ synchronized (syncObject) {
+ fcpConnection.close();
+ syncObject.notifyAll();
+ }
+ }
+
+ /**
+ * Returns whether this client is currently connected.
+ *
+ * @return {@code true} if the client is currently connected, {@code false}
+ * otherwise
+ */
+ public boolean isConnected() {
+ return connected;
+ }
+
+ //
+ // PEER MANAGEMENT
+ //
+
+ /**
+ * Returns all peers that the node has.
+ *
+ * @param withMetadata
+ * <code>true</code> to include peer metadata
+ * @param withVolatile
+ * <code>true</code> to include volatile peer data
+ * @return A set containing the node’s peers
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Collection<Peer> getPeers(final boolean withMetadata, final boolean withVolatile) throws IOException, FcpException {
+ final Set<Peer> peers = Collections.synchronizedSet(new HashSet<Peer>());
+ new ExtendedFcpAdapter() {
+
+ /** The ID of the “ListPeers” request. */
+ @SuppressWarnings("synthetic-access")
+ private String identifier = createIdentifier("list-peers");
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ fcpConnection.sendMessage(new ListPeers(identifier, withMetadata, withVolatile));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
+ if (peer.getIdentifier().equals(identifier)) {
+ peers.add(peer);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) {
+ if (endListPeers.getIdentifier().equals(identifier)) {
+ completionLatch.countDown();
+ }
+ }
+ }.execute();
+ return peers;
+ }
+
+ /**
+ * Returns all darknet peers.
+ *
+ * @param withMetadata
+ * <code>true</code> to include peer metadata
+ * @param withVolatile
+ * <code>true</code> to include volatile peer data
+ * @return A set containing the node’s darknet peers
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Collection<Peer> getDarknetPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
+ Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
+ Collection<Peer> darknetPeers = new HashSet<Peer>();
+ for (Peer peer : allPeers) {
+ if (!peer.isOpennet() && !peer.isSeed()) {
+ darknetPeers.add(peer);
+ }
+ }
+ return darknetPeers;
+ }
+
+ /**
+ * Returns all opennet peers.
+ *
+ * @param withMetadata
+ * <code>true</code> to include peer metadata
+ * @param withVolatile
+ * <code>true</code> to include volatile peer data
+ * @return A set containing the node’s opennet peers
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Collection<Peer> getOpennetPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
+ Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
+ Collection<Peer> opennetPeers = new HashSet<Peer>();
+ for (Peer peer : allPeers) {
+ if (peer.isOpennet() && !peer.isSeed()) {
+ opennetPeers.add(peer);
+ }
+ }
+ return opennetPeers;
+ }
+
+ /**
+ * Returns all seed peers.
+ *
+ * @param withMetadata
+ * <code>true</code> to include peer metadata
+ * @param withVolatile
+ * <code>true</code> to include volatile peer data
+ * @return A set containing the node’s seed peers
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Collection<Peer> getSeedPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
+ Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
+ Collection<Peer> seedPeers = new HashSet<Peer>();
+ for (Peer peer : allPeers) {
+ if (peer.isSeed()) {
+ seedPeers.add(peer);
+ }
+ }
+ return seedPeers;
+ }
+
+ /**
+ * Adds the given peer to the node.
+ *
+ * @param peer
+ * The peer to add
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void addPeer(Peer peer) throws IOException, FcpException {
+ addPeer(peer.getNodeRef());
+ }
+
+ /**
+ * Adds the peer defined by the noderef to the node.
+ *
+ * @param nodeRef
+ * The noderef that defines the new peer
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void addPeer(NodeRef nodeRef) throws IOException, FcpException {
+ addPeer(new AddPeer(nodeRef));
+ }
+
+ /**
+ * Adds a peer, reading the noderef from the given URL.
+ *
+ * @param url
+ * The URL to read the noderef from
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void addPeer(URL url) throws IOException, FcpException {
+ addPeer(new AddPeer(url));
+ }
+
+ /**
+ * Adds a peer, reading the noderef of the peer from the given file.
+ * <strong>Note:</strong> the file to read the noderef from has to reside on
+ * the same machine as the node!
+ *
+ * @param file
+ * The name of the file containing the peer’s noderef
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void addPeer(String file) throws IOException, FcpException {
+ addPeer(new AddPeer(file));
+ }
+
+ /**
+ * Sends the given {@link AddPeer} message to the node. This method should
+ * not be called directly. Use one of {@link #addPeer(Peer)},
+ * {@link #addPeer(NodeRef)}, {@link #addPeer(URL)}, or
+ * {@link #addPeer(String)} instead.
+ *
+ * @param addPeer
+ * The “AddPeer” message
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ private void addPeer(final AddPeer addPeer) throws IOException, FcpException {
+ new ExtendedFcpAdapter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ fcpConnection.sendMessage(addPeer);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
+ completionLatch.countDown();
+ }
+ }.execute();
+ }
+
+ /**
+ * Modifies the given peer.
+ *
+ * @param peer
+ * The peer to modify
+ * @param allowLocalAddresses
+ * <code>true</code> to allow local address, <code>false</code>
+ * to not allow local address, <code>null</code> to not change
+ * the setting
+ * @param disabled
+ * <code>true</code> to disable the peer, <code>false</code> to
+ * enable the peer, <code>null</code> to not change the setting
+ * @param listenOnly
+ * <code>true</code> to enable “listen only” for the peer,
+ * <code>false</code> to disable it, <code>null</code> to not
+ * change it
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void modifyPeer(final Peer peer, final Boolean allowLocalAddresses, final Boolean disabled, final Boolean listenOnly) throws IOException, FcpException {
+ new ExtendedFcpAdapter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ fcpConnection.sendMessage(new ModifyPeer(peer.getIdentity(), allowLocalAddresses, disabled, listenOnly));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
+ completionLatch.countDown();
+ }
+ }.execute();
+ }
+
+ /**
+ * Removes the given peer.
+ *
+ * @param peer
+ * The peer to remove
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void removePeer(final Peer peer) throws IOException, FcpException {
+ new ExtendedFcpAdapter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ fcpConnection.sendMessage(new RemovePeer(peer.getIdentity()));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) {
+ completionLatch.countDown();
+ }
+ }.execute();
+ }
+
+ //
+ // PEER NOTES MANAGEMENT
+ //
+
+ /**
+ * Returns the peer note of the given peer.
+ *
+ * @param peer
+ * The peer to get the note for
+ * @return The peer’s note
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public PeerNote getPeerNote(final Peer peer) throws IOException, FcpException {
+ final ObjectWrapper<PeerNote> objectWrapper = new ObjectWrapper<PeerNote>();
+ new ExtendedFcpAdapter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ fcpConnection.sendMessage(new ListPeerNotes(peer.getIdentity()));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) {
+ if (peerNote.getNodeIdentifier().equals(peer.getIdentity())) {
+ objectWrapper.set(peerNote);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) {
+ completionLatch.countDown();
+ }
+ }.execute();
+ return objectWrapper.get();
+ }
+
+ /**
+ * Replaces the peer note for the given peer.
+ *
+ * @param peer
+ * The peer
+ * @param noteText
+ * The new base64-encoded note text
+ * @param noteType
+ * The type of the note (currently only <code>1</code> is
+ * allowed)
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void modifyPeerNote(final Peer peer, final String noteText, final int noteType) throws IOException, FcpException {
+ new ExtendedFcpAdapter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ fcpConnection.sendMessage(new ModifyPeerNote(peer.getIdentity(), noteText, noteType));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedPeer(FcpConnection fcpConnection, Peer receivedPeer) {
+ if (receivedPeer.getIdentity().equals(peer.getIdentity())) {
+ completionLatch.countDown();
+ }
+ }
+ }.execute();
+ }
+
+ //
+ // KEY GENERATION
+ //
+
+ /**
+ * Generates a new SSK key pair.
+ *
+ * @return The generated key pair
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public SSKKeypair generateKeyPair() throws IOException, FcpException {
+ final ObjectWrapper<SSKKeypair> sskKeypairWrapper = new ObjectWrapper<SSKKeypair>();
+ new ExtendedFcpAdapter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ fcpConnection.sendMessage(new GenerateSSK());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
+ sskKeypairWrapper.set(sskKeypair);
+ completionLatch.countDown();
+ }
+ }.execute();
+ return sskKeypairWrapper.get();
+ }
+
+ //
+ // REQUEST MANAGEMENT
+ //
+
+ /**
+ * Returns all currently visible persistent get requests.
+ *
+ * @param global
+ * <code>true</code> to return get requests from the global
+ * queue, <code>false</code> to only show requests from the
+ * client-local queue
+ * @return All get requests
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Collection<Request> getGetRequests(final boolean global) throws IOException, FcpException {
+ return Filters.filteredCollection(getRequests(global), new Filter<Request>() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean filterObject(Request request) {
+ return request instanceof GetRequest;
+ }
+ });
+ }
+
+ /**
+ * Returns all currently visible persistent put requests.
+ *
+ * @param global
+ * <code>true</code> to return put requests from the global
+ * queue, <code>false</code> to only show requests from the
+ * client-local queue
+ * @return All put requests
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Collection<Request> getPutRequests(final boolean global) throws IOException, FcpException {
+ return Filters.filteredCollection(getRequests(global), new Filter<Request>() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean filterObject(Request request) {
+ return request instanceof PutRequest;
+ }
+ });
+ }
+
+ /**
+ * Returns all currently visible persistent requests.
+ *
+ * @param global
+ * <code>true</code> to return requests from the global queue,
+ * <code>false</code> to only show requests from the client-local
+ * queue
+ * @return All requests
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Collection<Request> getRequests(final boolean global) throws IOException, FcpException {
+ final Map<String, Request> requests = Collections.synchronizedMap(new HashMap<String, Request>());
+ new ExtendedFcpAdapter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ fcpConnection.sendMessage(new ListPersistentRequests());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) {
+ if (!persistentGet.isGlobal() || global) {
+ GetRequest getRequest = new GetRequest(persistentGet);
+ requests.put(persistentGet.getIdentifier(), getRequest);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see net.pterodactylus.fcp.FcpAdapter#receivedDataFound(net.pterodactylus.fcp.FcpConnection,
+ * net.pterodactylus.fcp.DataFound)
+ */
+ @Override
+ public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound) {
+ Request getRequest = requests.get(dataFound.getIdentifier());
+ if (getRequest == null) {
+ return;
+ }
+ getRequest.setComplete(true);
+ getRequest.setLength(dataFound.getDataLength());
+ getRequest.setContentType(dataFound.getMetadataContentType());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see net.pterodactylus.fcp.FcpAdapter#receivedGetFailed(net.pterodactylus.fcp.FcpConnection,
+ * net.pterodactylus.fcp.GetFailed)
+ */
+ @Override
+ public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) {
+ Request getRequest = requests.get(getFailed.getIdentifier());
+ if (getRequest == null) {
+ return;
+ }
+ getRequest.setComplete(true);
+ getRequest.setFailed(true);
+ getRequest.setFatal(getFailed.isFatal());
+ getRequest.setErrorCode(getFailed.getCode());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see net.pterodactylus.fcp.FcpAdapter#receivedPersistentPut(net.pterodactylus.fcp.FcpConnection,
+ * net.pterodactylus.fcp.PersistentPut)
+ */
+ @Override
+ public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut) {
+ if (!persistentPut.isGlobal() || global) {
+ PutRequest putRequest = new PutRequest(persistentPut);
+ requests.put(persistentPut.getIdentifier(), putRequest);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see net.pterodactylus.fcp.FcpAdapter#receivedSimpleProgress(net.pterodactylus.fcp.FcpConnection,
+ * net.pterodactylus.fcp.SimpleProgress)
+ */
+ @Override
+ public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) {
+ Request request = requests.get(simpleProgress.getIdentifier());
+ if (request == null) {
+ return;
+ }
+ request.setTotalBlocks(simpleProgress.getTotal());
+ request.setRequiredBlocks(simpleProgress.getRequired());
+ request.setFailedBlocks(simpleProgress.getFailed());
+ request.setFatallyFailedBlocks(simpleProgress.getFatallyFailed());
+ request.setSucceededBlocks(simpleProgress.getSucceeded());
+ request.setFinalizedTotal(simpleProgress.isFinalizedTotal());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests) {
+ completionLatch.countDown();
+ }
+ }.execute();
+ return requests.values();
+ }
+
+ /**
+ * Sends a message to a plugin and waits for the response.
+ *
+ * @param pluginClass
+ * The name of the plugin class
+ * @param parameters
+ * The parameters for the plugin
+ * @return The responses from the plugin
+ * @throws FcpException
+ * if an FCP error occurs
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public Map<String, String> sendPluginMessage(String pluginClass, Map<String, String> parameters) throws IOException, FcpException {
+ return sendPluginMessage(pluginClass, parameters, 0, null);
+ }
+
+ /**
+ * Sends a message to a plugin and waits for the response.
+ *
+ * @param pluginClass
+ * The name of the plugin class
+ * @param parameters
+ * The parameters for the plugin
+ * @param dataLength
+ * The length of the optional data stream, or {@code 0} if there
+ * is no optional data stream
+ * @param dataInputStream
+ * The input stream for the payload, or {@code null} if there is
+ * no payload
+ * @return The responses from the plugin
+ * @throws FcpException
+ * if an FCP error occurs
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public Map<String, String> sendPluginMessage(final String pluginClass, final Map<String, String> parameters, final long dataLength, final InputStream dataInputStream) throws IOException, FcpException {
+ final Map<String, String> pluginReplies = Collections.synchronizedMap(new HashMap<String, String>());
+ new ExtendedFcpAdapter() {
+
+ @SuppressWarnings("synthetic-access")
+ private final String identifier = createIdentifier("FCPPluginMessage");
+
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ FCPPluginMessage fcpPluginMessage = new FCPPluginMessage(pluginClass);
+ for (Entry<String, String> parameter : parameters.entrySet()) {
+ fcpPluginMessage.setParameter(parameter.getKey(), parameter.getValue());
+ }
+ fcpPluginMessage.setIdentifier(identifier);
+ if ((dataLength > 0) && (dataInputStream != null)) {
+ fcpPluginMessage.setDataLength(dataLength);
+ fcpPluginMessage.setPayloadInputStream(dataInputStream);
+ }
+ fcpConnection.sendMessage(fcpPluginMessage);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) {
+ if (!fcpPluginReply.getIdentifier().equals(identifier)) {
+ return;
+ }
+ pluginReplies.putAll(fcpPluginReply.getReplies());
+ completionLatch.countDown();
+ }
+
+ }.execute();
+ return pluginReplies;
+ }
+
+ //
+ // NODE INFORMATION
+ //
+
+ /**
+ * Returns information about the node.
+ *
+ * @param giveOpennetRef
+ * Whether to return the OpenNet reference
+ * @param withPrivate
+ * Whether to return private node data
+ * @param withVolatile
+ * Whether to return volatile node data
+ * @return Node information
+ * @throws FcpException
+ * if an FCP error occurs
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public NodeData getNodeInformation(final Boolean giveOpennetRef, final Boolean withPrivate, final Boolean withVolatile) throws IOException, FcpException {
+ final ObjectWrapper<NodeData> nodeDataWrapper = new ObjectWrapper<NodeData>();
+ new ExtendedFcpAdapter() {
+
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() throws IOException {
+ GetNode getNodeMessage = new GetNode(giveOpennetRef, withPrivate, withVolatile);
+ fcpConnection.sendMessage(getNodeMessage);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData) {
+ nodeDataWrapper.set(nodeData);
+ completionLatch.countDown();
+ }
+ }.execute();
+ return nodeDataWrapper.get();
+ }
+
+ //
+ // PRIVATE METHODS
+ //
+
+ /**
+ * Creates a unique request identifier.
+ *
+ * @param basename
+ * The basename of the request
+ * @return The created request identifier
+ */
+ private String createIdentifier(String basename) {
+ return basename + "-" + System.currentTimeMillis() + "-" + (int) (Math.random() * Integer.MAX_VALUE);
+ }
+
+ /**
+ * Checks whether the connection is in the required state.
+ *
+ * @param connected
+ * The required connection state
+ * @throws FcpException
+ * if the connection is not in the required state
+ */
+ private void checkConnected(boolean connected) throws FcpException {
+ if (this.connected != connected) {
+ throw new FcpException("Client is " + (connected ? "not" : "already") + " connected.");
+ }
+ }
+
+ /**
+ * Tells the client that it is now disconnected. This method is called by
+ * {@link ExtendedFcpAdapter} only.
+ */
+ private void setDisconnected() {
+ connected = false;
+ }
+
+ /**
+ * Implementation of an {@link FcpListener} that can store an
+ * {@link FcpException} and wait for the arrival of a certain command.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ private abstract class ExtendedFcpAdapter extends FcpAdapter {
+
+ /** The count down latch used to wait for completion. */
+ protected final CountDownLatch completionLatch = new CountDownLatch(1);
+
+ /** The FCP exception, if any. */
+ protected FcpException fcpException;
+
+ /**
+ * Creates a new extended FCP adapter.
+ */
+ public ExtendedFcpAdapter() {
+ /* do nothing. */
+ }
+
+ /**
+ * Executes the FCP commands in {@link #run()}, wrapping the execution
+ * and catching exceptions.
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ @SuppressWarnings("synthetic-access")
+ public void execute() throws IOException, FcpException {
+ checkConnected(true);
+ fcpConnection.addFcpListener(this);
+ try {
+ run();
+ while (true) {
+ try {
+ completionLatch.await();
+ break;
+ } catch (InterruptedException ie1) {
+ /* ignore, we’ll loop. */
+ }
+ }
+ } catch (IOException ioe1) {
+ setDisconnected();
+ throw ioe1;
+ } finally {
+ fcpConnection.removeFcpListener(this);
+ }
+ if (fcpException != null) {
+ setDisconnected();
+ throw fcpException;
+ }
+ }
+
+ /**
+ * The FCP commands that actually get executed.
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract void run() throws IOException;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
+ fcpException = new FcpException("Connection closed", throwable);
+ completionLatch.countDown();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
+ fcpException = new FcpException("Connection closed, duplicate client name");
+ completionLatch.countDown();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
+ fcpException = new FcpException("Protocol error (" + protocolError.getCode() + ", " + protocolError.getCodeDescription());
+ completionLatch.countDown();
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpClientListener.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import java.util.EventListener;
+
+/**
+ * Listener for {@link FcpClient} events.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public interface FcpClientListener extends EventListener {
+
+ /**
+ * Notifies a listener that the given FCP client was disconnected.
+ *
+ * @param fcpClient
+ * The FCP client that was disconnected
+ */
+ public void fcpClientDisconnected(FcpClient fcpClient);
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpClientListenerManager.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import net.pterodactylus.util.event.AbstractListenerManager;
+
+/**
+ * Manages {@link FcpClientListener}s and fires events.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class FcpClientListenerManager extends AbstractListenerManager<FcpClient, FcpClientListener> {
+
+ /**
+ * Creates a new FCP client listener manager.
+ *
+ * @param fcpClient
+ * The source FCP client
+ */
+ public FcpClientListenerManager(FcpClient fcpClient) {
+ super(fcpClient);
+ }
+
+ /**
+ * Notifies all listeners that the FCP client was disconnected.
+ *
+ * @see FcpClientListener#fcpClientDisconnected(FcpClient)
+ */
+ public void fireFcpClientDisconnected() {
+ for (FcpClientListener fcpClientListener : getListeners()) {
+ fcpClientListener.fcpClientDisconnected(getSource());
+ }
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - FcpException.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+/**
+ * Exception that signals an error in the FCP protocol.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class FcpException extends Exception {
+
+ /**
+ * Creates a new FCP exception.
+ */
+ public FcpException() {
+ super();
+ }
+
+ /**
+ * Creates a new FCP exception.
+ *
+ * @param message
+ * The message of the exception
+ */
+ public FcpException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a new FCP exception.
+ *
+ * @param cause
+ * The cause of the exception
+ */
+ public FcpException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates a new FCP exception.
+ *
+ * @param message
+ * The message of the exception
+ * @param cause
+ * The cause of the exception
+ */
+ public FcpException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - GetRequest.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import net.pterodactylus.fcp.PersistentGet;
+
+/**
+ * High-level wrapper around {@link PersistentGet}.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class GetRequest extends Request {
+
+ /**
+ * Creates a new get request.
+ *
+ * @param persistentGet
+ * The persistent Get request to wrap
+ */
+ GetRequest(PersistentGet persistentGet) {
+ super(persistentGet.getIdentifier(), persistentGet.getClientToken(), persistentGet.isGlobal());
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - PutRequest.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import net.pterodactylus.fcp.PersistentPut;
+
+/**
+ * TODO
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class PutRequest extends Request {
+
+ PutRequest(PersistentPut persistentPut) {
+ super(persistentPut.getIdentifier(), persistentPut.getClientToken(), persistentPut.isGlobal());
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - Request.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import net.pterodactylus.fcp.PersistentGet;
+import net.pterodactylus.fcp.PersistentPut;
+
+/**
+ * Wrapper class around request responses from the node, such as
+ * {@link PersistentGet} or {@link PersistentPut}.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public abstract class Request {
+
+ /** The identifier of the request. */
+ private final String identifier;
+
+ /** The client token of the request. */
+ private final String clientToken;
+
+ /** Whether the request is on the global queue. */
+ private final boolean global;
+
+ /** Whether the get request is complete. */
+ private boolean complete;
+
+ /** Whether the get request has failed. */
+ private boolean failed;
+
+ /** The data length. */
+ private long length;
+
+ /** The mime type. */
+ private String contentType;
+
+ /** The error code in case of failure. */
+ private int errorCode;
+
+ /** Whether the failure is fatal. */
+ private boolean fatal;
+
+ /** The total number of blocks. */
+ private int totalBlocks;
+
+ /** The required number of blocks. */
+ private int requiredBlocks;
+
+ /** The successfully processed number of blocks. */
+ private int succeededBlocks;
+
+ /** The number of failed blocks. */
+ private int failedBlocks;
+
+ /** The number of fatally failed blocks. */
+ private int fatallyFailedBlocks;
+
+ /** Whether the total number of blocks is finalized. */
+ private boolean finalizedTotal;
+
+ /**
+ * Creates a new request with the given identifier and client token.
+ *
+ * @param identifier
+ * The identifier of the request
+ * @param clientToken
+ * The client token of the request
+ * @param global
+ * <code>true</code> if the request is on the global queue,
+ * <code>false</code> otherwise
+ */
+ protected Request(String identifier, String clientToken, boolean global) {
+ this.identifier = identifier;
+ this.clientToken = clientToken;
+ this.global = global;
+ }
+
+ /**
+ * Returns the identifier of the request.
+ *
+ * @return The request’s identifier
+ */
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ /**
+ * Returns the client token of the request.
+ *
+ * @return The request’s client token
+ */
+ public String getClientToken() {
+ return clientToken;
+ }
+
+ /**
+ * Returns whether this request is on the global queue.
+ *
+ * @return <code>true</code> if the request is on the global queue,
+ * <code>false</code> otherwise
+ */
+ public boolean isGlobal() {
+ return global;
+ }
+
+ /**
+ * Returns whether this request is complete.
+ *
+ * @return <code>true</code> if this request is complete, false otherwise
+ */
+ public boolean isComplete() {
+ return complete;
+ }
+
+ /**
+ * Sets whether this request is complete.
+ *
+ * @param complete
+ * <code>true</code> if this request is complete, false otherwise
+ */
+ void setComplete(boolean complete) {
+ this.complete = complete;
+ }
+
+ /**
+ * Returns whether this request has failed. This method should only be
+ * called if {@link #isComplete()} returns <code>true</code>.
+ *
+ * @return <code>true</code> if this request failed, <code>false</code>
+ * otherwise
+ */
+ public boolean hasFailed() {
+ return failed;
+ }
+
+ /**
+ * Sets whether this request has failed.
+ *
+ * @param failed
+ * <code>true</code> if this request failed, <code>false</code>
+ * otherwise
+ */
+ void setFailed(boolean failed) {
+ this.failed = failed;
+ }
+
+ /**
+ * Returns the length of the data.
+ *
+ * @return The length of the data
+ */
+ public long getLength() {
+ return length;
+ }
+
+ /**
+ * Sets the length of the data.
+ *
+ * @param length
+ * The length of the data
+ */
+ void setLength(long length) {
+ this.length = length;
+ }
+
+ /**
+ * Returns the content type of the data.
+ *
+ * @return The content type of the data
+ */
+ public String getContentType() {
+ return contentType;
+ }
+
+ /**
+ * Sets the content type of the data.
+ *
+ * @param contentType
+ * The content type of the data
+ */
+ void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ /**
+ * Returns the error code. This method should only be called if
+ * {@link #hasFailed()} returns <code>true</code>.
+ *
+ * @return The error code
+ */
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ /**
+ * Sets the error code.
+ *
+ * @param errorCode
+ * The error code
+ */
+ void setErrorCode(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ /**
+ * Returns whether this request has fatally failed, i.e. repitition will not
+ * cause the request to succeed.
+ *
+ * @return <code>true</code> if this request can not be made succeed by
+ * repeating, <code>false</code> otherwise
+ */
+ public boolean isFatal() {
+ return fatal;
+ }
+
+ /**
+ * Sets whether this request has fatally failed.
+ *
+ * @param fatal
+ * <code>true</code> if this request failed fatally,
+ * <code>false</code> otherwise
+ */
+ void setFatal(boolean fatal) {
+ this.fatal = fatal;
+ }
+
+ /**
+ * Returns the total number of blocks of this request.
+ *
+ * @return This request’s total number of blocks
+ */
+ public int getTotalBlocks() {
+ return totalBlocks;
+ }
+
+ /**
+ * Sets the total number of blocks of this request.
+ *
+ * @param totalBlocks
+ * This request’s total number of blocks
+ */
+ public void setTotalBlocks(int totalBlocks) {
+ this.totalBlocks = totalBlocks;
+ }
+
+ /**
+ * TODO
+ *
+ * @return the requiredBlocks
+ */
+ public int getRequiredBlocks() {
+ return requiredBlocks;
+ }
+
+ /**
+ * TODO
+ *
+ * @param requiredBlocks
+ * the requiredBlocks to set
+ */
+ public void setRequiredBlocks(int requiredBlocks) {
+ this.requiredBlocks = requiredBlocks;
+ }
+
+ /**
+ * TODO
+ *
+ * @return the succeededBlocks
+ */
+ public int getSucceededBlocks() {
+ return succeededBlocks;
+ }
+
+ /**
+ * TODO
+ *
+ * @param succeededBlocks
+ * the succeededBlocks to set
+ */
+ public void setSucceededBlocks(int succeededBlocks) {
+ this.succeededBlocks = succeededBlocks;
+ }
+
+ /**
+ * TODO
+ *
+ * @return the failedBlocks
+ */
+ public int getFailedBlocks() {
+ return failedBlocks;
+ }
+
+ /**
+ * TODO
+ *
+ * @param failedBlocks
+ * the failedBlocks to set
+ */
+ public void setFailedBlocks(int failedBlocks) {
+ this.failedBlocks = failedBlocks;
+ }
+
+ /**
+ * TODO
+ *
+ * @return the fatallyFailedBlocks
+ */
+ public int getFatallyFailedBlocks() {
+ return fatallyFailedBlocks;
+ }
+
+ /**
+ * TODO
+ *
+ * @param fatallyFailedBlocks
+ * the fatallyFailedBlocks to set
+ */
+ public void setFatallyFailedBlocks(int fatallyFailedBlocks) {
+ this.fatallyFailedBlocks = fatallyFailedBlocks;
+ }
+
+ public boolean isFinalizedTotal() {
+ return finalizedTotal;
+ }
+
+ void setFinalizedTotal(boolean finalizedTotal) {
+ this.finalizedTotal = finalizedTotal;
+ }
+
+}
--- /dev/null
+/**
+ * Package that holds all the message types that are used in the communication
+ * with a Freenet Node.
+ *
+ * <h2>Usage</h2>
+ *
+ * This library was designed to implement the full range of the Freenet Client
+ * Protocol, Version 2.0. At the moment the library provides a rather low-level
+ * approach, wrapping each FCP message into its own object but some kind of
+ * high-level client that does not require any interfaces to be implemented
+ * will probably provided as well.
+ *
+ * First, create a connection to the node:
+ *
+ * <pre>
+ * FcpConnection fcpConnection = new FcpConnection();
+ * </pre>
+ *
+ * Now implement the {@link net.pterodactylus.fcp.FcpListener} interface
+ * and handle all incoming events.
+ *
+ * <pre>
+ * public class MyClass implements FcpListener {
+ *
+ * public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
+ * …
+ * }
+ *
+ * // implement all further methods here
+ *
+ * }
+ * </pre>
+ */
+
+package net.pterodactylus.fcp;
+
--- /dev/null
+/*
+ * jFCPlib - WebOfTrustPlugin.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.plugin;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import net.pterodactylus.fcp.highlevel.FcpClient;
+import net.pterodactylus.fcp.highlevel.FcpException;
+
+/**
+ * Simplifies handling of the web-of-trust plugin.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class WebOfTrustPlugin {
+
+ /** The FCP client to use. */
+ private final FcpClient fcpClient;
+
+ /**
+ * Creates a new web-of-trust plugin wrapper around the given FCP client.
+ *
+ * @param fcpClient
+ * The FCP client to use for communication with the web-of-trust
+ * plugin
+ */
+ public WebOfTrustPlugin(FcpClient fcpClient) {
+ this.fcpClient = fcpClient;
+ }
+
+ /**
+ * Creates a new identity.
+ *
+ * @param nickname
+ * The nickname of the new identity
+ * @param context
+ * The context for the new identity
+ * @param publishTrustList
+ * {@code true} if the new identity should publish its trust list
+ * @return The new identity
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList) throws IOException, FcpException {
+ return createIdentity(nickname, context, publishTrustList, null, null);
+ }
+
+ /**
+ * Creates a new identity from the given request and insert URI.
+ *
+ * @param nickname
+ * The nickname of the new identity
+ * @param context
+ * The context for the new identity
+ * @param publishTrustList
+ * {@code true} if the new identity should publish its trust list
+ * @param requestUri
+ * The request URI of the identity
+ * @param insertUri
+ * The insert URI of the identity
+ * @return The new identity
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList, String requestUri, String insertUri) throws IOException, FcpException {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put("Message", "CreateIdentity");
+ parameters.put("Nickname", nickname);
+ parameters.put("Context", context);
+ parameters.put("PublishTrustList", String.valueOf(publishTrustList));
+ if ((requestUri != null) && (insertUri != null)) {
+ parameters.put("RequestURI", requestUri);
+ parameters.put("InsertURI", insertUri);
+ }
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", parameters);
+ if (!replies.get("Message").equals("IdentityCreated")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “IdentityCreated” message!");
+ }
+ String identifier = replies.get("ID");
+ String newRequestUri = replies.get("RequestURI");
+ String newInsertUri = replies.get("InsertURI");
+ return new OwnIdentity(identifier, nickname, newRequestUri, newInsertUri);
+ }
+
+ /**
+ * Returns all own identities of the web-of-trust plugins. Almost all other
+ * commands require an {@link OwnIdentity} to return meaningful values.
+ *
+ * @return All own identities of the web-of-trust plugin
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Set<OwnIdentity> getOwnIdentites() throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetOwnIdentities"));
+ if (!replies.get("Message").equals("OwnIdentities")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “OwnIdentities” message!");
+ }
+ Set<OwnIdentity> ownIdentities = new HashSet<OwnIdentity>();
+ for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
+ String identity = replies.get("Identity" + identityIndex);
+ String nickname = replies.get("Nickname" + identityIndex);
+ String requestUri = replies.get("RequestURI" + identityIndex);
+ String insertUri = replies.get("InsertURI" + identityIndex);
+ ownIdentities.add(new OwnIdentity(identity, nickname, requestUri, insertUri));
+ }
+ return ownIdentities;
+ }
+
+ /**
+ * Returns the trust given to the identity with the given identifier by the
+ * given own identity.
+ *
+ * @param ownIdentity
+ * The own identity that is used to calculate trust values
+ * @param identifier
+ * The identifier of the identity whose trust to get
+ * @return The request identity trust
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public CalculatedTrust getIdentityTrust(OwnIdentity ownIdentity, String identifier) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentity", "TreeOwner", ownIdentity.getIdentifier(), "Identity", identifier));
+ if (!replies.get("Message").equals("Identity")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “Identity” message!");
+ }
+ Byte trust = null;
+ try {
+ trust = Byte.valueOf(replies.get("Trust"));
+ } catch (NumberFormatException nfe1) {
+ /* ignore. */
+ }
+ Integer score = null;
+ try {
+ score = Integer.valueOf(replies.get("Score"));
+ } catch (NumberFormatException nfe1) {
+ /* ignore. */
+ }
+ Integer rank = null;
+ try {
+ rank = Integer.valueOf(replies.get("Rank"));
+ } catch (NumberFormatException nfe1) {
+ /* ignore. */
+ }
+ return new CalculatedTrust(trust, score, rank);
+ }
+
+ /**
+ * Adds a new identity by its request URI.
+ *
+ * @param requestUri
+ * The request URI of the identity to add
+ * @return The added identity
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Identity addIdentity(String requestUri) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddIdentity", "RequestURI", requestUri));
+ if (!replies.get("Message").equals("IdentityAdded")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “IdentityAdded” message!");
+ }
+ String identifier = replies.get("ID");
+ String nickname = replies.get("Nickname");
+ return new Identity(identifier, nickname, requestUri);
+ }
+
+ /**
+ * Returns identities by the given score.
+ *
+ * @param ownIdentity
+ * The own identity
+ * @param context
+ * The context to get the identities for
+ * @param positive
+ * {@code null} to return neutrally trusted identities, {@code
+ * true} to return positively trusted identities, {@code false}
+ * for negatively trusted identities
+ * @return The trusted identites
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Set<Identity> getIdentitesByScore(OwnIdentity ownIdentity, String context, Boolean positive) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentitiesByScore", "TreeOwner", ownIdentity.getIdentifier(), "Context", context, "Selection", ((positive == null) ? "0" : (positive ? "+" : "-"))));
+ if (!replies.get("Message").equals("Identities")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
+ }
+ Set<Identity> identities = new HashSet<Identity>();
+ for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
+ String identifier = replies.get("Identity" + identityIndex);
+ String nickname = replies.get("Nickname" + identityIndex);
+ String requestUri = replies.get("RequestURI" + identityIndex);
+ identities.add(new Identity(identifier, nickname, requestUri));
+ }
+ return identities;
+ }
+
+ /**
+ * Returns the identities that trust the given identity.
+ *
+ * @param identity
+ * The identity to get the trusters for
+ * @param context
+ * The context to get the trusters for
+ * @return The identities and their trust values
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Map<Identity, IdentityTrust> getTrusters(Identity identity, String context) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrusters", "Identity", identity.getIdentifier(), "Context", context));
+ if (!replies.get("Message").equals("Identities")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
+ }
+ Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
+ for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
+ String identifier = replies.get("Identity" + identityIndex);
+ String nickname = replies.get("Nickname" + identityIndex);
+ String requestUri = replies.get("RequestURI" + identityIndex);
+ byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
+ String comment = replies.get("Comment" + identityIndex);
+ identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
+ }
+ return identityTrusts;
+ }
+
+ /**
+ * Returns the identities that given identity trusts.
+ *
+ * @param identity
+ * The identity to get the trustees for
+ * @param context
+ * The context to get the trustees for
+ * @return The identities and their trust values
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public Map<Identity, IdentityTrust> getTrustees(Identity identity, String context) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrustees", "Identity", identity.getIdentifier(), "Context", context));
+ if (!replies.get("Message").equals("Identities")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
+ }
+ Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
+ for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
+ String identifier = replies.get("Identity" + identityIndex);
+ String nickname = replies.get("Nickname" + identityIndex);
+ String requestUri = replies.get("RequestURI" + identityIndex);
+ byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
+ String comment = replies.get("Comment" + identityIndex);
+ identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
+ }
+ return identityTrusts;
+ }
+
+ /**
+ * Sets the trust given to the given identify by the given own identity.
+ *
+ * @param ownIdentity
+ * The identity that gives the trust
+ * @param identity
+ * The identity that receives the trust
+ * @param trust
+ * The trust value (ranging from {@code -100} to {@code 100}
+ * @param comment
+ * The comment for setting the trust
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void setTrust(OwnIdentity ownIdentity, Identity identity, byte trust, String comment) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetTrust", "Truster", ownIdentity.getIdentifier(), "Trustee", identity.getIdentifier(), "Value", String.valueOf(trust), "Comment", comment));
+ if (!replies.get("Message").equals("TrustSet")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “TrustSet” message!");
+ }
+ }
+
+ /**
+ * Adds the given context to the given identity.
+ *
+ * @param ownIdentity
+ * The identity to add the context to
+ * @param context
+ * The context to add
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void addContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
+ if (!replies.get("Message").equals("ContextAdded")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “ContextAdded” message!");
+ }
+ }
+
+ /**
+ * Removes the given context from the given identity.
+ *
+ * @param ownIdentity
+ * The identity to remove the context from
+ * @param context
+ * The context to remove
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void removeContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
+ if (!replies.get("Message").equals("ContextRemoved")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “ContextRemoved” message!");
+ }
+ }
+
+ /**
+ * Sets the given property for the given identity.
+ *
+ * @param ownIdentity
+ * The identity to set a property for
+ * @param property
+ * The name of the property to set
+ * @param value
+ * The value of the property to set
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void setProperty(OwnIdentity ownIdentity, String property, String value) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property, "Value", value));
+ if (!replies.get("Message").equals("PropertyAdded")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “PropertyAdded” message!");
+ }
+ }
+
+ /**
+ * Returns the value of the given property for the given identity.
+ *
+ * @param ownIdentity
+ * The identity to get a property for
+ * @param property
+ * The name of the property to get
+ * @return The value of the property
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public String getProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
+ if (!replies.get("Message").equals("PropertyValue")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “PropertyValue” message!");
+ }
+ return replies.get("Property");
+ }
+
+ /**
+ * Removes the given property from the given identity.
+ *
+ * @param ownIdentity
+ * The identity to remove a property from
+ * @param property
+ * The name of the property to remove
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws FcpException
+ * if an FCP error occurs
+ */
+ public void removeProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
+ Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
+ if (!replies.get("Message").equals("PropertyRemoved")) {
+ throw new FcpException("WebOfTrust Plugin did not reply with “PropertyRemoved” message!");
+ }
+ }
+
+ //
+ // PRIVATE METHODS
+ //
+
+ /**
+ * Creates a map from each pair of parameters in the given array.
+ *
+ * @param parameters
+ * The array of parameters
+ * @return The map created from the array
+ * @throws ArrayIndexOutOfBoundsException
+ * if the given parameter array does not contains an even number
+ * of elements
+ */
+ private Map<String, String> createParameters(String... parameters) throws ArrayIndexOutOfBoundsException {
+ Map<String, String> parameterMap = new HashMap<String, String>();
+ for (int index = 0; index < parameters.length; index += 2) {
+ parameterMap.put(parameters[index], parameters[index + 1]);
+ }
+ return parameterMap;
+ }
+
+ /**
+ * Wrapper around a web-of-trust identity.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ public static class Identity {
+
+ /** The identity’s identifier. */
+ private final String identifier;
+
+ /** The identity’s nickname. */
+ private final String nickname;
+
+ /** The identity’s request URI. */
+ private final String requestUri;
+
+ /**
+ * Creates a new identity.
+ *
+ * @param identifier
+ * The identifies of the identity
+ * @param nickname
+ * The nickname of the identity
+ * @param requestUri
+ * The request URI of the identity
+ */
+ public Identity(String identifier, String nickname, String requestUri) {
+ this.identifier = identifier;
+ this.nickname = nickname;
+ this.requestUri = requestUri;
+ }
+
+ /**
+ * Returns the identifier of this identity.
+ *
+ * @return This identity’s identifier
+ */
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ /**
+ * Returns the nickname of this identity.
+ *
+ * @return This identity’s nickname
+ */
+ public String getNickname() {
+ return nickname;
+ }
+
+ /**
+ * Returns the request URI of this identity.
+ *
+ * @return This identity’s request URI
+ */
+ public String getRequestUri() {
+ return requestUri;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if ((obj == null) || (obj.getClass() != this.getClass())) {
+ return false;
+ }
+ Identity identity = (Identity) obj;
+ return identifier.equals(identity.identifier);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return identifier.hashCode();
+ }
+
+ }
+
+ /**
+ * Container for the trust given from one identity to another.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ public static class IdentityTrust {
+
+ /** The trust given to the identity. */
+ private final byte trust;
+
+ /** The command for the trust value. */
+ private final String comment;
+
+ /**
+ * Creates a new identity trust container.
+ *
+ * @param trust
+ * The trust given to the identity
+ * @param comment
+ * The comment for the trust value
+ */
+ public IdentityTrust(byte trust, String comment) {
+ this.trust = trust;
+ this.comment = comment;
+ }
+
+ /**
+ * Returns the trust value given to the identity.
+ *
+ * @return The trust value
+ */
+ public byte getTrust() {
+ return trust;
+ }
+
+ /**
+ * Returns the comment for the trust value.
+ *
+ * @return The comment for the trust value
+ */
+ public String getComment() {
+ return comment;
+ }
+
+ }
+
+ /**
+ * Container that stores the trust that is calculated by taking all trustees
+ * and their trust lists into account.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ public static class CalculatedTrust {
+
+ /** The calculated trust value. */
+ private final Byte trust;
+
+ /** The calculated score value. */
+ private final Integer score;
+
+ /** The calculated rank. */
+ private final Integer rank;
+
+ /**
+ * Creates a new calculated trust container.
+ *
+ * @param trust
+ * The calculated trust value
+ * @param score
+ * The calculated score value
+ * @param rank
+ * The calculated rank of the
+ */
+ public CalculatedTrust(Byte trust, Integer score, Integer rank) {
+ this.trust = trust;
+ this.score = score;
+ this.rank = rank;
+ }
+
+ /**
+ * Returns the calculated trust value.
+ *
+ * @return The calculated trust value, or {@code null} if the trust
+ * value is not known
+ */
+ public Byte getTrust() {
+ return trust;
+ }
+
+ /**
+ * Returns the calculated score value.
+ *
+ * @return The calculated score value, or {@code null} if the score
+ * value is not known
+ */
+ public Integer getScore() {
+ return score;
+ }
+
+ /**
+ * Returns the calculated rank.
+ *
+ * @return The calculated rank, or {@code null} if the rank is not known
+ */
+ public Integer getRank() {
+ return rank;
+ }
+
+ }
+
+ /**
+ * Wrapper around a web-of-trust own identity.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ public static class OwnIdentity extends Identity {
+
+ /** The identity’s insert URI. */
+ private final String insertUri;
+
+ /**
+ * Creates a new web-of-trust own identity.
+ *
+ * @param identifier
+ * The identifier of the identity
+ * @param nickname
+ * The nickname of the identity
+ * @param requestUri
+ * The request URI of the identity
+ * @param insertUri
+ * The insert URI of the identity
+ */
+ public OwnIdentity(String identifier, String nickname, String requestUri, String insertUri) {
+ super(identifier, nickname, requestUri);
+ this.insertUri = insertUri;
+ }
+
+ /**
+ * Returns the insert URI of this identity.
+ *
+ * @return This identity’s insert URI
+ */
+ public String getInsertUri() {
+ return insertUri;
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - AbstractListenerManager.java - Copyright © 2009 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.util.event;
+
+import java.util.EventListener;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+
+import net.pterodactylus.util.thread.CurrentThreadExecutor;
+
+/**
+ * Abstract implementation of a listener support class. The listener support
+ * takes care of adding and removing {@link EventListener} implementations, and
+ * subclasses are responsible for firing appropriate events.
+ *
+ * @param <S>
+ * The type of the source
+ *@param <L>
+ * The type of the event listeners
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public abstract class AbstractListenerManager<S, L extends EventListener> {
+
+ /** The source that emits the events. */
+ private final S source;
+
+ /** The list of listeners. */
+ private final List<L> listeners = new CopyOnWriteArrayList<L>();
+
+ /** Service that executes event threads. */
+ private final Executor executor;
+
+ /**
+ * Creates a new listener support that emits events from the given source.
+ *
+ * @param source
+ * The source of the events
+ */
+ public AbstractListenerManager(S source) {
+ this(source, new CurrentThreadExecutor());
+ }
+
+ /**
+ * Creates a new listener support that emits events from the given source.
+ *
+ * @param source
+ * The source of the events
+ * @param executor
+ * The executor used to fire events
+ */
+ public AbstractListenerManager(S source, Executor executor) {
+ this.source = source;
+ this.executor = executor;
+ }
+
+ /**
+ * Adds the given listener to the list of reigstered listeners.
+ *
+ * @param listener
+ * The listener to add
+ */
+ public void addListener(L listener) {
+ synchronized (listeners) {
+ listeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes the given listener from the list of registered listeners.
+ *
+ * @param listener
+ * The listener to remove
+ */
+ public void removeListener(L listener) {
+ synchronized (listeners) {
+ listeners.remove(listener);
+ }
+ }
+
+ //
+ // PROTECTED METHODS
+ //
+
+ /**
+ * Returns the source for the events.
+ *
+ * @return The event source
+ */
+ protected S getSource() {
+ return source;
+ }
+
+ /**
+ * Returns the executor for the event firing.
+ *
+ * @return The executor
+ */
+ protected Executor getExecutor() {
+ return executor;
+ }
+
+ /**
+ * Returns a list of all registered listeners. The returned list is a copy
+ * of the original list so structural modifications will never occur when
+ * using the returned list.
+ *
+ * @return The list of all registered listeners
+ */
+ protected List<L> getListeners() {
+ return listeners;
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - Filter.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+package net.pterodactylus.util.filter;
+
+/**
+ * Interface for a filter that determines whether a certain action can be
+ * performed on an object based on its properties.
+ *
+ * @param <T>
+ * The type of the filtered object
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public interface Filter<T> {
+
+ /**
+ * Runs the given object through this filter and return whether the object
+ * matches this filter or not.
+ *
+ * @param object
+ * The object to analyse
+ * @return <code>true</code> if the object matched this filter,
+ * <code>false</code> otherwise
+ */
+ public boolean filterObject(T object);
+
+}
--- /dev/null
+/*
+ * jFCPlib - Filters.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+package net.pterodactylus.util.filter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * Defines various methods to filter {@link Collection}s.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class Filters {
+
+ /**
+ * Returns a list that contains only the elements from the given list that
+ * match the given filter.
+ *
+ * @param <E>
+ * The type of the list elements
+ * @param list
+ * The list to filter
+ * @param listFilter
+ * The list filter
+ * @return The filtered list
+ */
+ public static <E> List<E> filteredList(List<E> list, Filter<E> listFilter) {
+ List<E> filteredList = new ArrayList<E>();
+ for (E element : list) {
+ if (listFilter.filterObject(element)) {
+ filteredList.add(element);
+ }
+ }
+ return filteredList;
+ }
+
+ /**
+ * Returns a set that contains only the elements from the given set that
+ * match the given filter.
+ *
+ * @param <E>
+ * The type of the set elements
+ * @param set
+ * The set to filter
+ * @param setFilter
+ * The set filter
+ * @return The filtered set
+ */
+ public static <E> Set<E> filteredSet(Set<E> set, Filter<E> setFilter) {
+ Set<E> filteredSet = new HashSet<E>();
+ for (E element : set) {
+ if (setFilter.filterObject(element)) {
+ filteredSet.add(element);
+ }
+ }
+ return filteredSet;
+ }
+
+ /**
+ * Returns a map that contains only the elements from the given map that
+ * match the given filter.
+ *
+ * @param <K>
+ * The type of the map keys
+ * @param <V>
+ * The type of the map values
+ * @param map
+ * The map to filter
+ * @param mapFilter
+ * The map filter
+ * @return The filtered map
+ */
+ public static <K, V> Map<K, V> filteredMap(Map<K, V> map, Filter<Entry<K, V>> mapFilter) {
+ Map<K, V> filteredMap = new HashMap<K, V>();
+ for (Entry<K, V> element : map.entrySet()) {
+ if (mapFilter.filterObject(element)) {
+ filteredMap.put(element.getKey(), element.getValue());
+ }
+ }
+ return filteredMap;
+ }
+
+ /**
+ * Returns a collection that contains only the elements from the given
+ * collection that match the given filter.
+ *
+ * @param <K>
+ * The type of the collection values
+ * @param collection
+ * The collection to filter
+ * @param collectionFilter
+ * The collection filter
+ * @return The filtered collection
+ */
+ public static <K> Collection<K> filteredCollection(Collection<K> collection, Filter<K> collectionFilter) {
+ return filteredList(new ArrayList<K>(collection), collectionFilter);
+ }
+
+ /**
+ * Returns an iterator that contains only the elements from the given
+ * iterator that match the given filter.
+ *
+ * @param <E>
+ * The type of the iterator elements
+ * @param iterator
+ * The iterator to filter
+ * @param iteratorFilter
+ * The iterator filter
+ * @return The filtered iterator
+ */
+ public static <E> Iterator<E> filteredIterator(final Iterator<E> iterator, final Filter<E> iteratorFilter) {
+ return new Iterator<E>() {
+
+ private boolean gotNextElement = false;
+
+ private E nextElement;
+
+ private void getNextElement() {
+ if (gotNextElement) {
+ return;
+ }
+ while (iterator.hasNext()) {
+ nextElement = iterator.next();
+ if (iteratorFilter.filterObject(nextElement)) {
+ gotNextElement = true;
+ break;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ getNextElement();
+ return gotNextElement;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Iterator#next()
+ */
+ public E next() {
+ getNextElement();
+ if (!gotNextElement) {
+ throw new NoSuchElementException("no more elements in iteration");
+ }
+ gotNextElement = false;
+ return nextElement;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Iterator#remove()
+ */
+ public void remove() {
+ throw new UnsupportedOperationException("remove() not supported on this iteration");
+ }
+
+ };
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - CurrentThreadExecutor.java - Copyright © 2009 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.util.thread;
+
+import java.util.concurrent.Executor;
+
+/**
+ * An {@link Executor} that executes {@link Runnable}s in the current thread.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class CurrentThreadExecutor implements Executor {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.concurrent.Executor#execute(java.lang.Runnable)
+ */
+ public void execute(Runnable command) {
+ command.run();
+ }
+
+}
--- /dev/null
+/*
+ * jFCPlib - UserObject.java - Copyright © 2009 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.util.thread;
+
+/**
+ * Wrapper around an object that can be set and retrieved. Its primary use is as
+ * a container for return values from anonymous classes.
+ *
+ * <pre>
+ * final ObjectWrapper<Object> objectWrapper = new ObjectWrapper<Object>();
+ * new Runnable() {
+ * public void run() {
+ * ...
+ * objectWrapper.set(someResult);
+ * }
+ * }.run();
+ * Object result = objectWrapper.get();
+ * </pre>
+ *
+ * @param <T>
+ * The type of the wrapped object
+ * @author David ‘Bombe’ Roden <bombe@pterodactylus.net>
+ */
+public class ObjectWrapper<T> {
+
+ /** The wrapped object. */
+ private volatile T wrappedObject;
+
+ /**
+ * Returns the wrapped object.
+ *
+ * @return The wrapped object
+ */
+ public T get() {
+ return wrappedObject;
+ }
+
+ /**
+ * Sets the wrapped object.
+ *
+ * @param wrappedObject
+ * The wrapped object
+ */
+ public void set(T wrappedObject) {
+ this.wrappedObject = wrappedObject;
+ }
+
+}
+++ /dev/null
-/*
- * jFCPlib - ARK.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Container for ARKs (address resolution keys).
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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;
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - AbstractSendFeedMessage.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Abstract base implementation for the {@code Send*Feed} commands.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public abstract class AbstractSendFeedMessage extends FcpMessage {
-
- /**
- * Creates a new “Send*Feed” command.
- *
- * @param name
- * The name of the command
- * @param identifier
- * The identifier of the request
- * @param nodeIdentifier
- * The identifier of the peer node
- */
- protected AbstractSendFeedMessage(String name, String identifier, String nodeIdentifier) {
- super(name);
- setField("Identifier", identifier);
- setField("NodeIdentifier", nodeIdentifier);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - AddPeer.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.net.URL;
-
-/**
- * The “AddPeer” request adds a peer to the node.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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());
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - AllData.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.InputStream;
-
-/**
- * The “AllData” message carries the payload of a successful {@link ClientGet}
- * request. You will only received this message if the {@link ClientGet} request
- * was started with a return type of {@link ReturnType#direct}. If you get this
- * message and decide that the data is for you, call
- * {@link #getPayloadInputStream()} to get the data. If an AllData message
- * passes through all registered {@link FcpListener}s without the payload being
- * consumed, the payload is discarded!
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class AllData extends BaseMessage {
-
- /** The payload. */
- private InputStream payloadInputStream;
-
- /**
- * Creates an “AllData” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- * @param payloadInputStream
- * The payload
- */
- AllData(FcpMessage receivedMessage, InputStream payloadInputStream) {
- super(receivedMessage);
- this.payloadInputStream = payloadInputStream;
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the length of the data.
- *
- * @return The length of the data, or <code>-1</code> if the length could
- * not be parsed
- */
- public long getDataLength() {
- return FcpUtils.safeParseLong(getField("DataLength"));
- }
-
- /**
- * Returns the startup time of the request.
- *
- * @return The startup time of the request (in milliseconds since Jan 1,
- * 1970 UTC), or <code>-1</code> if the time could not be parsed
- */
- public long getStartupTime() {
- return FcpUtils.safeParseLong(getField("StartupTime"));
- }
-
- /**
- * Returns the completion time of the request.
- *
- * @return The completion time of the request (in milliseconds since Jan 1,
- * 1970 UTC), or <code>-1</code> if the time could not be parsed
- */
- public long getCompletionTime() {
- return FcpUtils.safeParseLong(getField("CompletionTime"));
- }
-
- /**
- * Returns the payload input stream. You <strong>have</strong> consume the
- * input stream before returning from the
- * {@link FcpListener#receivedAllData(FcpConnection, AllData)} method!
- *
- * @return The payload
- */
- public InputStream getPayloadInputStream() {
- return payloadInputStream;
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - BaseMessage.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.Map;
-
-/**
- * A basic message abstraction that wraps a received FCP message.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class BaseMessage {
-
- /** The received message, wrapped here. */
- private final FcpMessage receivedMessage;
-
- /**
- * Creates a new base message that wraps the given message.
- *
- * @param receivedMessage
- * The FCP message that was received
- */
- BaseMessage(FcpMessage receivedMessage) {
- this.receivedMessage = receivedMessage;
- }
-
- /**
- * Returns the name of the message.
- *
- * @return The name of the message
- */
- public String getName() {
- return receivedMessage.getName();
- }
-
- /**
- * Returns the content of the field.
- *
- * @param field
- * The name of the field
- * @return The content of the field, or <code>null</code> if there is no
- * such field
- */
- protected String getField(String field) {
- return receivedMessage.getField(field);
- }
-
- /**
- * Returns all fields from the received message.
- *
- * @see FcpMessage#getFields()
- * @return All fields from the message
- */
- protected Map<String, String> getFields() {
- return receivedMessage.getFields();
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ClientGet.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ClientGet” request is used for download files from the Freenet node.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ClientGet extends FcpMessage {
-
- /**
- * Creates a new “ClientGet” request.
- *
- * @param uri
- * The URI to get
- * @param identifier
- * The identifier of the request
- */
- public ClientGet(String uri, String identifier) {
- this(uri, identifier, ReturnType.direct);
- }
-
- /**
- * Creates a new “ClientGet” request.
- *
- * @param uri
- * The URI to get
- * @param identifier
- * The identifier of the request
- * @param returnType
- * The return type of the request
- */
- public ClientGet(String uri, String identifier, ReturnType returnType) {
- super("ClientGet");
- setField("URI", uri);
- setField("Identifier", identifier);
- setField("ReturnType", String.valueOf(returnType));
- }
-
- /**
- * Sets whether the local data store should be ignored when searching for a
- * key.
- *
- * @param ignoreDataStore
- * <code>true</code> to ignore the local data store,
- * <code>false</code> to include it
- */
- public void setIgnoreDataStore(boolean ignoreDataStore) {
- setField("IgnoreDS", String.valueOf(ignoreDataStore));
- }
-
- /**
- * Sets whether the search for the key should be restricted to the local
- * data store only.
- *
- * @param dsOnly
- * <code>true</code> to restrict the search to the local data
- * store, <code>false</code> to search on other nodes, too
- */
- public void setDataStoreOnly(boolean dsOnly) {
- setField("DSonly", String.valueOf(dsOnly));
- }
-
- /**
- * Sets the verbosity of the request.
- *
- * @param verbosity
- * The verbosity of the request
- */
- public void setVerbosity(Verbosity verbosity) {
- setField("Verbosity", String.valueOf(verbosity));
- }
-
- /**
- * Sets the maximum size of the file to retrieve. If the file is larger than
- * this size the request will fail!
- *
- * @param maxSize
- * The maximum size of the file to retrieve
- */
- public void setMaxSize(long maxSize) {
- setField("MaxSize", String.valueOf(maxSize));
- }
-
- /**
- * Sets the maximum size of temporary files created by the node. If a
- * temporary file is larger than this size the request will fail!
- *
- * @param maxTempSize
- * The maximum size of temporary files
- */
- public void setMaxTempSize(long maxTempSize) {
- setField("MaxTempSize", String.valueOf(maxTempSize));
- }
-
- /**
- * The maximum number of retries in case a block can not be retrieved.
- *
- * @param maxRetries
- * The maximum number of retries for failed blocks,
- * <code>-1</code> to try forever
- */
- public void setMaxRetries(int maxRetries) {
- setField("MaxRetries", String.valueOf(maxRetries));
- }
-
- /**
- * Sets the priority of the request.
- *
- * @param priority
- * The priority of the request
- */
- public void setPriority(Priority priority) {
- setField("PriorityClass", String.valueOf(priority));
- }
-
- /**
- * Sets the persistence of the request.
- *
- * @param persistence
- * The persistence of the request
- */
- public void setPersistence(Persistence persistence) {
- setField("Persistence", String.valueOf(persistence));
- }
-
- /**
- * Sets the client token of the request.
- *
- * @param clientToken
- * The client token of the request
- */
- public void setClientToken(String clientToken) {
- setField("ClientToken", clientToken);
- }
-
- /**
- * Sets whether the request should be visible on the global queue.
- *
- * @param global
- * <code>true</code> to make the request visible on the global
- * queue, <code>false</code> for client-local queue only
- */
- public void setGlobal(boolean global) {
- setField("Global", String.valueOf(global));
- }
-
- /**
- * Sets whether to request the “binary blob” for a key.
- *
- * @param binaryBlob
- * <code>true</code> to request the binary blob,
- * <code>false</code> to get the “real thing”
- */
- public void setBinaryBlob(boolean binaryBlob) {
- setField("BinaryBlob", String.valueOf(binaryBlob));
- }
-
- /**
- * Sets the allowed MIME types of the requested file. If the MIME type of
- * the file does not match one of the given MIME types the request will
- * fail!
- *
- * @param allowedMimeTypes
- * The allowed MIME types
- */
- public void setAllowedMimeTypes(String... allowedMimeTypes) {
- setField("AllowedMIMETypes", FcpUtils.encodeMultiStringField(allowedMimeTypes));
- }
-
- /**
- * Sets the filename to download the file to. You should only call this
- * method if your return type is {@link ReturnType#disk}!
- *
- * @param filename
- * The filename to download the file to
- */
- public void setFilename(String filename) {
- setField("Filename", filename);
- }
-
- /**
- * Sets the name for the temporary file. You should only call this method if
- * your return type is {@link ReturnType#disk}!
- *
- * @param tempFilename
- * The name of the temporary file
- */
- public void setTempFilename(String tempFilename) {
- setField("TempFilename", tempFilename);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ClientHello.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ClientHello” message that <i>must</i> be sent to the node first thing
- * after calling {@link FcpConnection#connect()}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ClientPut.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ClientPut” requests inserts a single file into freenet, either uploading
- * it directly with this messge ({@link UploadFrom#direct}), uploading it from
- * disk ({@link UploadFrom#disk}) or by creating a redirect to another URI (
- * {@link UploadFrom#redirect}).
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ClientPut extends FcpMessage {
-
- /**
- * Creates a new “ClientPut” message that inserts a file to the given URI.
- * The file data <em>has</em> to be supplied to this message using
- * {@link #setPayloadInputStream(java.io.InputStream)}! Using this
- * constructor is the same as using
- * {@link #ClientPut(String, String, UploadFrom)} with
- * {@link UploadFrom#direct} as third parameter.
- *
- * @param uri
- * The URI to insert the file to
- * @param identifier
- * The identifier of the request
- */
- public ClientPut(String uri, String identifier) {
- this(uri, identifier, UploadFrom.direct);
- }
-
- /**
- * Creates a new “ClientPut” message that inserts a file to the given URI.
- * Depending on <code>uploadFrom</code> the file data has to be supplied in
- * different ways: If <code>uploadFrom</code> is {@link UploadFrom#direct},
- * use {@link #setPayloadInputStream(java.io.InputStream)} to supply the
- * input data. If <code>uploadFrom</code> is {@link UploadFrom#disk}, use
- * {@link #setFilename(String)} to supply the file to upload. You have to
- * test your direct-disk access (see {@link TestDDARequest},
- * {@link TestDDAReply}, {@link TestDDAResponse}, {@link TestDDAComplete})
- * before using this option! If <code>uploadFrom</code> is
- * {@link UploadFrom#redirect}, use {@link #setTargetURI(String)} to set the
- * target URI of the redirect.
- *
- * @param uri
- * The URI to insert to
- * @param identifier
- * The identifier of the insert
- * @param uploadFrom
- * The source of the upload
- */
- public ClientPut(String uri, String identifier, UploadFrom uploadFrom) {
- super("ClientPut");
- setField("URI", uri);
- setField("Identifier", identifier);
- setField("UploadFrom", String.valueOf(uploadFrom));
- }
-
- /**
- * The MIME type of the content.
- *
- * @param metadataContentType
- * The MIME type of the content
- */
- public void setMetadataContentType(String metadataContentType) {
- setField("Metadata.ContentType", metadataContentType);
- }
-
- /**
- * The verbosity of the request. Depending on this parameter you will
- * received only the bare minimum of messages for the request (i.e. “it
- * completed”) or a whole lot more.
- *
- * @see Verbosity
- * @param verbosity
- * The verbosity of the request
- */
- public void setVerbosity(Verbosity verbosity) {
- setField("Verbosity", String.valueOf(verbosity));
- }
-
- /**
- * The number of retries for a request if the initial try failed.
- *
- * @param maxRetries
- * The maximum number of retries after failure, or
- * <code>-1</code> to retry forever.
- */
- public void setMaxRetries(int maxRetries) {
- setField("MaxRetries", String.valueOf(maxRetries));
- }
-
- /**
- * Sets the priority of the request.
- *
- * @param priority
- * The priority of the request
- */
- public void setPriority(Priority priority) {
- setField("PriorityClass", String.valueOf(priority));
- }
-
- /**
- * Determines whether the node should really insert the data or generate the
- * final CHK only.
- *
- * @param getCHKOnly
- * <code>true</code> to generate the final CHK only,
- * <code>false</code> to really insert the data
- */
- public void setGetCHKOnly(boolean getCHKOnly) {
- setField("GetCHKOnly", String.valueOf(getCHKOnly));
- }
-
- /**
- * Determines whether this request appears on the global queue.
- *
- * @param global
- * <code>true</code> to put the request on the global queue,
- * <code>false</code> for the client-local queue.
- */
- public void setGlobal(boolean global) {
- setField("Global", String.valueOf(global));
- }
-
- /**
- * Determines whether the node should skip compression because the file has
- * already been compressed.
- *
- * @param dontCompress
- * <code>true</code> to skip compression of the data in the node,
- * <code>false</code> to allow compression
- */
- public void setDontCompress(boolean dontCompress) {
- setField("DontCompress", String.valueOf(dontCompress));
- }
-
- /**
- * Sets an optional client token. This client token is mentioned in progress
- * and other request-related messages and can be used to identify this
- * request.
- *
- * @param clientToken
- * The client token
- */
- public void setClientToken(String clientToken) {
- setField("ClientToken", clientToken);
- }
-
- /**
- * Sets the persistence of this request.
- *
- * @param persistence
- * The persistence of this request
- */
- public void setPersistence(Persistence persistence) {
- setField("Persistence", String.valueOf(persistence));
- }
-
- /**
- * Sets the target filename of the inserted file. This value is ignored for
- * all inserts that do not have “CHK@” as a target.
- *
- * @param targetFilename
- * The filename of the target
- */
- public void setTargetFilename(String targetFilename) {
- setField("TargetFilename", targetFilename);
- }
-
- /**
- * Determines whether to encode the complete file early in the life of the
- * request.
- *
- * @param earlyEncode
- * <code>true</code> to generate the final key long before the
- * file is completely fetchable
- */
- public void setEarlyEncode(boolean earlyEncode) {
- setField("EarlyEncode", String.valueOf(earlyEncode));
- }
-
- /**
- * Sets the length of the data that will be transferred after this message
- * if <code>uploadFrom</code> is {@link UploadFrom#direct} is used.
- *
- * @param dataLength
- * The length of the data
- */
- public void setDataLength(long dataLength) {
- setField("DataLength", String.valueOf(dataLength));
- }
-
- /**
- * Sets the name of the file to upload the data from.
- *
- * @param filename
- * The filename to upload
- */
- public void setFilename(String filename) {
- setField("Filename", filename);
- }
-
- /**
- * If <code>uploadFrom</code> is {@link UploadFrom#redirect}, use this
- * method to determine that target of the redirect.
- *
- * @param targetURI
- * The target URI to redirect to
- */
- public void setTargetURI(String targetURI) {
- setField("TargetURI", targetURI);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ClientPutComplexDir.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.SequenceInputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import net.pterodactylus.fcp.FileEntry.DirectFileEntry;
-
-/**
- * The “ClientPutComplexDir” lets you upload a directory with different sources
- * for each file.
- *
- * @see FileEntry
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ClientPutComplexDir extends FcpMessage {
-
- /** The index for added file entries. */
- private int fileIndex = 0;
-
- /** The input streams from {@link DirectFileEntry}s. */
- private final List<InputStream> directFileInputStreams = new ArrayList<InputStream>();
-
- /**
- * Creates a new “ClientPutComplexDir” with the given identifier and URI.
- *
- * @param identifier
- * The identifier of the request
- * @param uri
- * The URI to insert the directory to
- */
- public ClientPutComplexDir(String identifier, String uri) {
- super("ClientPutComplexDir");
- setField("Identifier", identifier);
- setField("URI", uri);
- }
-
- /**
- * Sets the verbosity of the request.
- *
- * @param verbosity
- * The verbosity of the request
- */
- public void setVerbosity(Verbosity verbosity) {
- setField("Verbosity", String.valueOf(verbosity));
- }
-
- /**
- * Sets the maximum number of retries for failed blocks.
- *
- * @param maxRetries
- * The maximum number of retries for failed blocks, or
- * <code>-1</code> to retry endlessly
- */
- public void setMaxRetries(int maxRetries) {
- setField("MaxRetries", String.valueOf(maxRetries));
- }
-
- /**
- * Sets the priority of the request.
- *
- * @param priority
- * The priority of the request
- */
- public void setPriority(Priority priority) {
- setField("PriorityClass", String.valueOf(priority));
- }
-
- /**
- * Sets whether to generate the final URI only.
- *
- * @param getCHKOnly
- * <code>true</code> to generate the final CHK only,
- * <code>false</code> to complete the insert
- */
- public void setGetCHKOnly(boolean getCHKOnly) {
- setField("GetCHKOnly", String.valueOf(getCHKOnly));
- }
-
- /**
- * Sets whether the request is on the global queue.
- *
- * @param global
- * <code>true</code> to put the request on the global queue,
- * <code>false</code> to put it on the client-local queue
- */
- public void setGlobal(boolean global) {
- setField("Global", String.valueOf(global));
- }
-
- /**
- * Sets whether the node should not try to compress the data.
- *
- * @param dontCompress
- * <code>true</code> to skip compression of the data,
- * <code>false</code> to try and compress the data
- */
- public void setDontCompress(boolean dontCompress) {
- setField("DontCompress", String.valueOf(dontCompress));
- }
-
- /**
- * Sets the client token of the request.
- *
- * @param clientToken
- * The client token of the request
- */
- public void setClientToken(String clientToken) {
- setField("ClientToken", clientToken);
- }
-
- /**
- * Sets the persistence of the request.
- *
- * @param persistence
- * The persistence of the request
- */
- public void setPersistence(Persistence persistence) {
- setField("Persistence", String.valueOf(persistence));
- }
-
- /**
- * Sets the target filename of the request. This is useful for inserts that
- * go to “CHK@” only and creates a manifest with a single file.
- *
- * @param targetFilename
- * The target filename
- */
- public void setTargetFilename(String targetFilename) {
- setField("TargetFilename", targetFilename);
- }
-
- /**
- * Sets whether to encode the complete data early to generate the
- * {@link URIGenerated} message early.
- *
- * @param earlyEncode
- * <code>true</code> to encode the complete data early,
- * <code>false</code> otherwise
- */
- public void setEarlyEncode(boolean earlyEncode) {
- setField("EarlyEncode", String.valueOf(earlyEncode));
- }
-
- /**
- * Sets the default name. This is the name of the file that should be shown
- * if no file was specified.
- *
- * @param defaultName
- * The default name
- */
- public void setDefaultName(String defaultName) {
- setField("DefaultName", defaultName);
- }
-
- /**
- * Adds an entry for a file.
- *
- * @param fileEntry
- * The file entry to add
- */
- public void addFileEntry(FileEntry fileEntry) {
- Map<String, String> fields = fileEntry.getFields();
- for (Entry<String, String> fieldEntry : fields.entrySet()) {
- setField("Files." + fileIndex + "." + fieldEntry.getKey(), fieldEntry.getValue());
- }
- fileIndex++;
- if (fileEntry instanceof FileEntry.DirectFileEntry) {
- directFileInputStreams.add(((DirectFileEntry) fileEntry).getInputStream());
- }
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Do not call this method to add input streams! The input streams, if any,
- * will be taken directly from the {@link FileEntry}s and the stream you set
- * here will be overridden!
- */
- @Override
- public void setPayloadInputStream(InputStream payloadInputStream) {
- /* do nothing. */
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void write(OutputStream outputStream) throws IOException {
- /* create payload stream. */
- setPayloadInputStream(new SequenceInputStream(Collections.enumeration(directFileInputStreams)));
- /* write out all the fields. */
- super.write(outputStream);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ClientPutDiskDir.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ClientPutDiskDir” message is used to insert a complete directory from
- * the disk to a single key.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ClientPutDiskDir extends FcpMessage {
-
- /**
- * Creates a new “ClientPutDiskDir” message.
- *
- * @param uri
- * The URI to insert the file to
- * @param identifier
- * The identifier of the request
- * @param directory
- * The name of the directory to insert
- */
- public ClientPutDiskDir(String uri, String identifier, String directory) {
- super("ClientPutDiskDir");
- setField("URI", uri);
- setField("Identifier", identifier);
- setField("Filename", directory);
- }
-
- /**
- * The verbosity of the request. Depending on this parameter you will
- * received only the bare minimum of messages for the request (i.e. “it
- * completed”) or a whole lot more.
- *
- * @see Verbosity
- * @param verbosity
- * The verbosity of the request
- */
- public void setVerbosity(Verbosity verbosity) {
- setField("Verbosity", String.valueOf(verbosity));
- }
-
- /**
- * The number of retries for a request if the initial try failed.
- *
- * @param maxRetries
- * The maximum number of retries after failure, or
- * <code>-1</code> to retry forever.
- */
- public void setMaxRetries(int maxRetries) {
- setField("MaxRetries", String.valueOf(maxRetries));
- }
-
- /**
- * Sets the priority of the request.
- *
- * @param priority
- * The priority of the request
- */
- public void setPriority(Priority priority) {
- setField("PriorityClass", String.valueOf(priority));
- }
-
- /**
- * Determines whether the node should really insert the data or generate the
- * final CHK only.
- *
- * @param getCHKOnly
- * <code>true</code> to generate the final CHK only,
- * <code>false</code> to really insert the data
- */
- public void setGetCHKOnly(boolean getCHKOnly) {
- setField("GetCHKOnly", String.valueOf(getCHKOnly));
- }
-
- /**
- * Determines whether this request appears on the global queue.
- *
- * @param global
- * <code>true</code> to put the request on the global queue,
- * <code>false</code> for the client-local queue.
- */
- public void setGlobal(boolean global) {
- setField("Global", String.valueOf(global));
- }
-
- /**
- * Determines whether the node should skip compression because the file has
- * already been compressed.
- *
- * @param dontCompress
- * <code>true</code> to skip compression of the data in the node,
- * <code>false</code> to allow compression
- */
- public void setDontCompress(boolean dontCompress) {
- setField("DontCompress", String.valueOf(dontCompress));
- }
-
- /**
- * Sets an optional client token. This client token is mentioned in progress
- * and other request-related messages and can be used to identify this
- * request.
- *
- * @param clientToken
- * The client token
- */
- public void setClientToken(String clientToken) {
- setField("ClientToken", clientToken);
- }
-
- /**
- * Sets the persistence of this request.
- *
- * @param persistence
- * The persistence of this request
- */
- public void setPersistence(Persistence persistence) {
- setField("Persistence", String.valueOf(persistence));
- }
-
- /**
- * Sets the name of the default file. The default file is shown when the key
- * is requested with an additional name.
- *
- * @param defaultName
- * The name of the default file
- */
- public void setDefaultName(String defaultName) {
- setField("DefaultName", defaultName);
- }
-
- /**
- * Sets whether unreadable files allow the insert to continue.
- *
- * @param allowUnreadableFiles
- * <code>true</code> to just ignore unreadable files,
- * <code>false</code> to let the insert fail when an unreadable
- * file is encountered
- */
- public void setAllowUnreadableFiles(boolean allowUnreadableFiles) {
- setField("AllowUnreadableFiles", String.valueOf(allowUnreadableFiles));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - CloseConnectionDuplicateClientName.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “CloseConnectionDuplicateClientName” message.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ConfigData.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ConfigData” message contains various aspects of the node’s configuration.
- *
- * @see GetConfig
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ConfigData extends BaseMessage {
-
- /**
- * Creates a new “ConfigData” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- ConfigData(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the current value of the given option.
- *
- * @param option
- * The name of the option
- * @return The current value of the option
- */
- public String getCurrent(String option) {
- return getField("current." + option);
- }
-
- /**
- * Returns the short description of the given option.
- *
- * @param option
- * The name of the option
- * @return The short description of the option
- */
- public String getShortDescription(String option) {
- return getField("shortDescription." + option);
- }
-
- /**
- * Returns the long description of the given option.
- *
- * @param option
- * The name of the option
- * @return The long description of the option
- */
- public String getLongDescription(String option) {
- return getField("longDescription." + option);
- }
-
- /**
- * Returns the data type of the given option.
- *
- * @param option
- * The name of the option
- * @return The data type of the option
- */
- public String getDataType(String option) {
- return getField("dataType." + option);
- }
-
- /**
- * Returns the default value of the given option.
- *
- * @param option
- * The name of the option
- * @return The default value of the option
- */
- public String getDefault(String option) {
- return getField("default." + option);
- }
-
- /**
- * Returns the sort order of the given option.
- *
- * @param option
- * The name of the option
- * @return The sort order of the option, or <code>-1</code> if the sort
- * order could not be parsed
- */
- public int getSortOrder(String option) {
- return FcpUtils.safeParseInt(getField("sortOrder." + option));
- }
-
- /**
- * Returns the expert flag of the given option.
- *
- * @param option
- * The name of the option
- * @return The expert flag of the option
- */
- public boolean getExpertFlag(String option) {
- return Boolean.valueOf(getField("expertFlag." + option));
- }
-
- /**
- * Returns the force-write flag of the given option
- *
- * @param option
- * The name of the option
- * @return The force-write flag of the given option
- */
- public boolean getForceWriteFlag(String option) {
- return Boolean.valueOf(getField("forceWriteFlag." + option));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - DSAGroup.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.security.interfaces.DSAParams;
-
-/**
- * Container for the DSA group of a peer. A DSA group consists of a base (called
- * “g”), a prime (called “p”) and a subprime (called “q”).
- *
- * @see DSAParams
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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;
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - DataFound.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “DataFound” message signals the client that the data requested by a
- * {@link ClientGet} operation has been found. This message does not include the
- * actual data, though.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class DataFound extends BaseMessage {
-
- /**
- * Creates a new “DataFound” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- DataFound(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns whether the request is on the global queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> if the request is on the client-local queue
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the content type of the data.
- *
- * @return The content type of the data
- */
- public String getMetadataContentType() {
- return getField("Metadata.ContentType");
- }
-
- /**
- * Returns the length of the data.
- *
- * @return The length of the data
- */
- public long getDataLength() {
- return FcpUtils.safeParseLong(getField("DataLength"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - EndListPeerNotes.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “EndListPeerNotes” message signals the end of a list of “PeerNote”
- * messages.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - EndListPeers.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * This message marks the end of a list of “Peer” replies.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class EndListPeers extends BaseMessage {
-
- /**
- * Creates a new “EndListPeers” message that wraps the received message.
- *
- * @param receivedMessage
- * The message that was received
- */
- EndListPeers(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - EndListPersistentRequests.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “EndListPersistentRequests” message signals the end of a list of
- * {@link PersistentGet} and {@link PersistentPut} requests.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PluginMessage.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * An “CPPluginMessage” sends a message with custom parameters and (optional)
- * payload to a plugin.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FCPPluginReply.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The “FCPPluginReply” is sent by a plugin as a response to a
- * {@link FCPPluginMessage} message.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FCPPluginReply extends BaseMessage {
-
- /** The payload input stream. */
- private final InputStream payloadInputStream;
-
- /**
- * Creates a new “FCPPluginReply” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- * @param payloadInputStream
- * The optional input stream for the payload
- */
- FCPPluginReply(FcpMessage receivedMessage, InputStream payloadInputStream) {
- super(receivedMessage);
- this.payloadInputStream = payloadInputStream;
- }
-
- /**
- * Returns the name of the plugin.
- *
- * @return The name of the plugin
- */
- public String getPluginName() {
- return getField("PluginName");
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the length of the optional payload.
- *
- * @return The length of the payload, or <code>-1</code> if there is no
- * payload or the length could not be parsed
- */
- public long getDataLength() {
- return FcpUtils.safeParseLong(getField("DataLength"));
- }
-
- /**
- * Returns a reply from the plugin.
- *
- * @param key
- * The name of the reply
- * @return The value of the reply
- */
- public String getReply(String key) {
- return getField("Replies." + key);
- }
-
- /**
- * Returns all replies from the plugin. The plugin sends replies as normal
- * message fields prefixed by “Replies.”. The keys of the returned map do
- * not contain this prefix!
- *
- * @return All replies from the plugin
- */
- public Map<String, String> getReplies() {
- Map<String, String> fields = getFields();
- Map<String, String> replies = new HashMap<String, String>();
- for (Entry<String, String> field : fields.entrySet()) {
- if (field.getKey().startsWith("Replies.")) {
- replies.put(field.getKey().substring(8), field.getValue());
- }
- }
- return replies;
- }
-
- /**
- * Returns the optional payload.
- *
- * @return The payload of the reply, or <code>null</code> if there is no
- * payload
- */
- public InputStream getPayloadInputStream() {
- return payloadInputStream;
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpAdapter.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Adapter for {@link FcpListener}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpAdapter implements FcpListener {
-
- /**
- * {@inheritDoc}
- */
- public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- *
- * @see FcpListener#receivedNodeData(FcpConnection, NodeData)
- */
- public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- *
- * @see FcpListener#receivedTestDDAReply(FcpConnection, TestDDAReply)
- */
- public void receivedTestDDAReply(FcpConnection fcpConnection, TestDDAReply testDDAReply) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedTestDDAComplete(FcpConnection fcpConnection, TestDDAComplete testDDAComplete) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedURIGenerated(FcpConnection fcpConnection, URIGenerated uriGenerated) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedAllData(FcpConnection fcpConnection, AllData allData) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedStartedCompression(FcpConnection fcpConnection, StartedCompression startedCompression) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedFinishedCompression(FcpConnection fcpConnection, FinishedCompression finishedCompression) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedUnknownPeerNoteType(FcpConnection fcpConnection, UnknownPeerNoteType unknownPeerNoteType) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedUnknownNodeIdentifier(FcpConnection fcpConnection, UnknownNodeIdentifier unknownNodeIdentifier) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedConfigData(FcpConnection fcpConnection, ConfigData configData) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPutFailed(FcpConnection fcpConnection, PutFailed putFailed) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedIdentifierCollision(FcpConnection fcpConnection, IdentifierCollision identifierCollision) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPersistentPutDir(FcpConnection fcpConnection, PersistentPutDir persistentPutDir) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedSubscribedUSKUpdate(FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPersistentRequestModified(FcpConnection fcpConnection, PersistentRequestModified persistentRequestModified) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPutSuccessful(FcpConnection fcpConnection, PutSuccessful putSuccessful) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedPutFetchable(FcpConnection fcpConnection, PutFetchable putFetchable) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedSentFeed(FcpConnection source, SentFeed sentFeed) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedBookmarkFeed(FcpConnection fcpConnection, ReceivedBookmarkFeed receivedBookmarkFeed) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage) {
- /* empty. */
- }
-
- /**
- * {@inheritDoc}
- */
- public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
- /* empty. */
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FpcConnection.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.Closeable;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
-
-/**
- * An FCP connection to a Freenet node.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpConnection implements Closeable {
-
- /** Logger. */
- private static final Logger logger = Logger.getLogger(FcpConnection.class.getName());
-
- /** The default port for FCP v2. */
- public static final int DEFAULT_PORT = 9481;
-
- /** Listener management. */
- private final FcpListenerManager fcpListenerManager = new FcpListenerManager(this);
-
- /** The address of the node. */
- private final InetAddress address;
-
- /** The port number of the node’s FCP port. */
- private final int port;
-
- /** The remote socket. */
- private Socket remoteSocket;
-
- /** The input stream from the node. */
- private InputStream remoteInputStream;
-
- /** The output stream to the node. */
- private OutputStream remoteOutputStream;
-
- /** The connection handler. */
- private FcpConnectionHandler connectionHandler;
-
- /** Incoming message statistics. */
- private Map<String, Integer> incomingMessageStatistics = Collections.synchronizedMap(new HashMap<String, Integer>());
-
- /**
- * Creates a new FCP connection to the freenet node running on localhost,
- * using the default port.
- *
- * @throws UnknownHostException
- * if the hostname can not be resolved
- */
- public FcpConnection() throws UnknownHostException {
- this(InetAddress.getLocalHost());
- }
-
- /**
- * Creates a new FCP connection to the Freenet node running on the given
- * host, listening on the default port.
- *
- * @param host
- * The hostname of the Freenet node
- * @throws UnknownHostException
- * if <code>host</code> can not be resolved
- */
- public FcpConnection(String host) throws UnknownHostException {
- this(host, DEFAULT_PORT);
- }
-
- /**
- * Creates a new FCP connection to the Freenet node running on the given
- * host, listening on the given port.
- *
- * @param host
- * The hostname of the Freenet node
- * @param port
- * The port number of the node’s FCP port
- * @throws UnknownHostException
- * if <code>host</code> can not be resolved
- */
- public FcpConnection(String host, int port) throws UnknownHostException {
- this(InetAddress.getByName(host), port);
- }
-
- /**
- * Creates a new FCP connection to the Freenet node running at the given
- * address, listening on the default port.
- *
- * @param address
- * The address of the Freenet node
- */
- public FcpConnection(InetAddress address) {
- this(address, DEFAULT_PORT);
- }
-
- /**
- * Creates a new FCP connection to the Freenet node running at the given
- * address, listening on the given port.
- *
- * @param address
- * The address of the Freenet node
- * @param port
- * The port number of the node’s FCP port
- */
- public FcpConnection(InetAddress address, int port) {
- this.address = address;
- this.port = port;
- }
-
- //
- // LISTENER MANAGEMENT
- //
-
- /**
- * Adds the given listener to the list of listeners.
- *
- * @param fcpListener
- * The listener to add
- */
- public void addFcpListener(FcpListener fcpListener) {
- fcpListenerManager.addListener(fcpListener);
- }
-
- /**
- * Removes the given listener from the list of listeners.
- *
- * @param fcpListener
- * The listener to remove
- */
- public void removeFcpListener(FcpListener fcpListener) {
- fcpListenerManager.removeListener(fcpListener);
- }
-
- //
- // ACTIONS
- //
-
- /**
- * Connects to the node.
- *
- * @throws IOException
- * if an I/O error occurs
- * @throws IllegalStateException
- * if there is already a connection to the node
- */
- public synchronized void connect() throws IOException, IllegalStateException {
- if (connectionHandler != null) {
- throw new IllegalStateException("already connected, disconnect first");
- }
- logger.info("connecting to " + address + ":" + port + "…");
- remoteSocket = new Socket(address, port);
- remoteInputStream = remoteSocket.getInputStream();
- remoteOutputStream = remoteSocket.getOutputStream();
- new Thread(connectionHandler = new FcpConnectionHandler(this, remoteInputStream)).start();
- }
-
- /**
- * Disconnects from the node. If there is no connection to the node, this
- * method does nothing.
- *
- * @deprecated Use {@link #close()} instead
- */
- @Deprecated
- public synchronized void disconnect() {
- close();
- }
-
- /**
- * Closes the connection. If there is no connection to the node, this method
- * does nothing.
- */
- public void close() {
- handleDisconnect(null);
- }
-
- /**
- * Sends the given FCP message.
- *
- * @param fcpMessage
- * The FCP message to send
- * @throws IOException
- * if an I/O error occurs
- */
- public synchronized void sendMessage(FcpMessage fcpMessage) throws IOException {
- logger.fine("sending message: " + fcpMessage.getName());
- fcpMessage.write(remoteOutputStream);
- }
-
- //
- // PACKAGE-PRIVATE METHODS
- //
-
- /**
- * Handles the given message, notifying listeners. This message should only
- * be called by {@link FcpConnectionHandler}.
- *
- * @param fcpMessage
- * The received message
- */
- void handleMessage(FcpMessage fcpMessage) {
- logger.fine("received message: " + fcpMessage.getName());
- String messageName = fcpMessage.getName();
- countMessage(messageName);
- if ("SimpleProgress".equals(messageName)) {
- fcpListenerManager.fireReceivedSimpleProgress(new SimpleProgress(fcpMessage));
- } else if ("ProtocolError".equals(messageName)) {
- fcpListenerManager.fireReceivedProtocolError(new ProtocolError(fcpMessage));
- } else if ("PersistentGet".equals(messageName)) {
- fcpListenerManager.fireReceivedPersistentGet(new PersistentGet(fcpMessage));
- } else if ("PersistentPut".equals(messageName)) {
- fcpListenerManager.fireReceivedPersistentPut(new PersistentPut(fcpMessage));
- } else if ("PersistentPutDir".equals(messageName)) {
- fcpListenerManager.fireReceivedPersistentPutDir(new PersistentPutDir(fcpMessage));
- } else if ("URIGenerated".equals(messageName)) {
- fcpListenerManager.fireReceivedURIGenerated(new URIGenerated(fcpMessage));
- } else if ("EndListPersistentRequests".equals(messageName)) {
- fcpListenerManager.fireReceivedEndListPersistentRequests(new EndListPersistentRequests(fcpMessage));
- } else if ("Peer".equals(messageName)) {
- fcpListenerManager.fireReceivedPeer(new Peer(fcpMessage));
- } else if ("PeerNote".equals(messageName)) {
- fcpListenerManager.fireReceivedPeerNote(new PeerNote(fcpMessage));
- } else if ("StartedCompression".equals(messageName)) {
- fcpListenerManager.fireReceivedStartedCompression(new StartedCompression(fcpMessage));
- } else if ("FinishedCompression".equals(messageName)) {
- fcpListenerManager.fireReceivedFinishedCompression(new FinishedCompression(fcpMessage));
- } else if ("GetFailed".equals(messageName)) {
- fcpListenerManager.fireReceivedGetFailed(new GetFailed(fcpMessage));
- } else if ("PutFetchable".equals(messageName)) {
- fcpListenerManager.fireReceivedPutFetchable(new PutFetchable(fcpMessage));
- } else if ("PutSuccessful".equals(messageName)) {
- fcpListenerManager.fireReceivedPutSuccessful(new PutSuccessful(fcpMessage));
- } else if ("PutFailed".equals(messageName)) {
- fcpListenerManager.fireReceivedPutFailed(new PutFailed(fcpMessage));
- } else if ("DataFound".equals(messageName)) {
- fcpListenerManager.fireReceivedDataFound(new DataFound(fcpMessage));
- } else if ("SubscribedUSKUpdate".equals(messageName)) {
- fcpListenerManager.fireReceivedSubscribedUSKUpdate(new SubscribedUSKUpdate(fcpMessage));
- } else if ("IdentifierCollision".equals(messageName)) {
- fcpListenerManager.fireReceivedIdentifierCollision(new IdentifierCollision(fcpMessage));
- } else if ("AllData".equals(messageName)) {
- LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength")));
- fcpListenerManager.fireReceivedAllData(new AllData(fcpMessage, payloadInputStream));
- try {
- payloadInputStream.consume();
- } catch (IOException ioe1) {
- /* well, ignore. when the connection handler fails, all fails. */
- }
- } else if ("EndListPeerNotes".equals(messageName)) {
- fcpListenerManager.fireReceivedEndListPeerNotes(new EndListPeerNotes(fcpMessage));
- } else if ("EndListPeers".equals(messageName)) {
- fcpListenerManager.fireReceivedEndListPeers(new EndListPeers(fcpMessage));
- } else if ("SSKKeypair".equals(messageName)) {
- fcpListenerManager.fireReceivedSSKKeypair(new SSKKeypair(fcpMessage));
- } else if ("PeerRemoved".equals(messageName)) {
- fcpListenerManager.fireReceivedPeerRemoved(new PeerRemoved(fcpMessage));
- } else if ("PersistentRequestModified".equals(messageName)) {
- fcpListenerManager.fireReceivedPersistentRequestModified(new PersistentRequestModified(fcpMessage));
- } else if ("PersistentRequestRemoved".equals(messageName)) {
- fcpListenerManager.fireReceivedPersistentRequestRemoved(new PersistentRequestRemoved(fcpMessage));
- } else if ("UnknownPeerNoteType".equals(messageName)) {
- fcpListenerManager.fireReceivedUnknownPeerNoteType(new UnknownPeerNoteType(fcpMessage));
- } else if ("UnknownNodeIdentifier".equals(messageName)) {
- fcpListenerManager.fireReceivedUnknownNodeIdentifier(new UnknownNodeIdentifier(fcpMessage));
- } else if ("FCPPluginReply".equals(messageName)) {
- LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength")));
- fcpListenerManager.fireReceivedFCPPluginReply(new FCPPluginReply(fcpMessage, payloadInputStream));
- try {
- payloadInputStream.consume();
- } catch (IOException ioe1) {
- /* ignore. */
- }
- } else if ("PluginInfo".equals(messageName)) {
- fcpListenerManager.fireReceivedPluginInfo(new PluginInfo(fcpMessage));
- } else if ("NodeData".equals(messageName)) {
- fcpListenerManager.fireReceivedNodeData(new NodeData(fcpMessage));
- } else if ("TestDDAReply".equals(messageName)) {
- fcpListenerManager.fireReceivedTestDDAReply(new TestDDAReply(fcpMessage));
- } else if ("TestDDAComplete".equals(messageName)) {
- fcpListenerManager.fireReceivedTestDDAComplete(new TestDDAComplete(fcpMessage));
- } else if ("ConfigData".equals(messageName)) {
- fcpListenerManager.fireReceivedConfigData(new ConfigData(fcpMessage));
- } else if ("NodeHello".equals(messageName)) {
- fcpListenerManager.fireReceivedNodeHello(new NodeHello(fcpMessage));
- } else if ("CloseConnectionDuplicateClientName".equals(messageName)) {
- fcpListenerManager.fireReceivedCloseConnectionDuplicateClientName(new CloseConnectionDuplicateClientName(fcpMessage));
- } else if ("SentFeed".equals(messageName)) {
- fcpListenerManager.fireSentFeed(new SentFeed(fcpMessage));
- } else if ("ReceivedBookmarkFeed".equals(messageName)) {
- fcpListenerManager.fireReceivedBookmarkFeed(new ReceivedBookmarkFeed(fcpMessage));
- } else {
- fcpListenerManager.fireMessageReceived(fcpMessage);
- }
- }
-
- /**
- * Handles a disconnect from the node.
- *
- * @param throwable
- * The exception that caused the disconnect, or <code>null</code>
- * if there was no exception
- */
- synchronized void handleDisconnect(Throwable throwable) {
- FcpUtils.close(remoteInputStream);
- FcpUtils.close(remoteOutputStream);
- FcpUtils.close(remoteSocket);
- if (connectionHandler != null) {
- connectionHandler.stop();
- connectionHandler = null;
- fcpListenerManager.fireConnectionClosed(throwable);
- }
- }
-
- //
- // PRIVATE METHODS
- //
-
- /**
- * Incremets the counter in {@link #incomingMessageStatistics} by
- * <cod>1</code> for the given message name.
- *
- * @param name
- * The name of the message to count
- */
- private void countMessage(String name) {
- int oldValue = 0;
- if (incomingMessageStatistics.containsKey(name)) {
- oldValue = incomingMessageStatistics.get(name);
- }
- incomingMessageStatistics.put(name, oldValue + 1);
- logger.finest("count for " + name + ": " + (oldValue + 1));
- }
-
- /**
- * Returns a limited input stream from the node’s input stream.
- *
- * @param dataLength
- * The length of the stream
- * @return The limited input stream
- */
- private synchronized LimitedInputStream getInputStream(long dataLength) {
- if (dataLength <= 0) {
- return new LimitedInputStream(null, 0);
- }
- return new LimitedInputStream(remoteInputStream, dataLength);
- }
-
- /**
- * A wrapper around an {@link InputStream} that only supplies a limit number
- * of bytes from the underlying input stream.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- private static class LimitedInputStream extends FilterInputStream {
-
- /** The remaining number of bytes that can be read. */
- private long remaining;
-
- /**
- * Creates a new LimitedInputStream that supplies at most
- * <code>length</code> bytes from the given input stream.
- *
- * @param inputStream
- * The input stream
- * @param length
- * The number of bytes to read
- */
- public LimitedInputStream(InputStream inputStream, long length) {
- super(inputStream);
- remaining = length;
- }
-
- /**
- * @see java.io.FilterInputStream#available()
- */
- @Override
- public synchronized int available() throws IOException {
- if (remaining == 0) {
- return 0;
- }
- return (int) Math.min(super.available(), Math.min(Integer.MAX_VALUE, remaining));
- }
-
- /**
- * @see java.io.FilterInputStream#read()
- */
- @Override
- public synchronized int read() throws IOException {
- int read = -1;
- if (remaining > 0) {
- read = super.read();
- remaining--;
- }
- return read;
- }
-
- /**
- * @see java.io.FilterInputStream#read(byte[], int, int)
- */
- @Override
- public synchronized int read(byte[] b, int off, int len) throws IOException {
- if (remaining == 0) {
- return -1;
- }
- int toCopy = (int) Math.min(len, Math.min(remaining, Integer.MAX_VALUE));
- int read = super.read(b, off, toCopy);
- remaining -= read;
- return read;
- }
-
- /**
- * @see java.io.FilterInputStream#skip(long)
- */
- @Override
- public synchronized long skip(long n) throws IOException {
- if ((n < 0) || (remaining == 0)) {
- return 0;
- }
- long skipped = super.skip(Math.min(n, remaining));
- remaining -= skipped;
- return skipped;
- }
-
- /**
- * {@inheritDoc} This method does nothing, as {@link #mark(int)} and
- * {@link #reset()} are not supported.
- *
- * @see java.io.FilterInputStream#mark(int)
- */
- @Override
- public void mark(int readlimit) {
- /* do nothing. */
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.io.FilterInputStream#markSupported()
- * @return <code>false</code>
- */
- @Override
- public boolean markSupported() {
- return false;
- }
-
- /**
- * {@inheritDoc} This method does nothing, as {@link #mark(int)} and
- * {@link #reset()} are not supported.
- *
- * @see java.io.FilterInputStream#reset()
- */
- @Override
- public void reset() throws IOException {
- /* do nothing. */
- }
-
- /**
- * Consumes the input stream, i.e. read all bytes until the limit is
- * reached.
- *
- * @throws IOException
- * if an I/O error occurs
- */
- public synchronized void consume() throws IOException {
- while (remaining > 0) {
- skip(remaining);
- }
- }
-
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpConnectionHandler.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-/**
- * Handles an FCP connection to a node.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-class FcpConnectionHandler implements Runnable {
-
- /** The underlying connection. */
- private final FcpConnection fcpConnection;
-
- /** The input stream from the node. */
- private final InputStream remoteInputStream;
-
- /** Whether to stop the connection handler. */
- private boolean shouldStop;
-
- /** Whether the next read line feed should be ignored. */
- private boolean ignoreNextLinefeed;
-
- /**
- * Creates a new connection handler that operates on the given connection
- * and input stream.
- *
- * @param fcpConnection
- * The underlying FCP connection
- * @param remoteInputStream
- * The input stream from the node
- */
- public FcpConnectionHandler(FcpConnection fcpConnection, InputStream remoteInputStream) {
- this.fcpConnection = fcpConnection;
- this.remoteInputStream = remoteInputStream;
- }
-
- /**
- * {@inheritDoc}
- */
- public void run() {
- FcpMessage fcpMessage = null;
- Throwable throwable = null;
- while (true) {
- synchronized (this) {
- if (shouldStop) {
- break;
- }
- }
- try {
- String line = readLine();
- System.out.println("read line: " + line);
- if (line == null) {
- break;
- }
- if (line.length() == 0) {
- continue;
- }
- line = line.trim();
- if (fcpMessage == null) {
- fcpMessage = new FcpMessage(line);
- continue;
- }
- if ("EndMessage".equalsIgnoreCase(line) || "Data".equalsIgnoreCase(line)) {
- fcpConnection.handleMessage(fcpMessage);
- fcpMessage = null;
- }
- int equalSign = line.indexOf('=');
- if (equalSign == -1) {
- /* something's fishy! */
- continue;
- }
- String field = line.substring(0, equalSign);
- String value = line.substring(equalSign + 1);
- assert fcpMessage != null: "fcp message is null";
- fcpMessage.setField(field, value);
- } catch (IOException ioe1) {
- throwable = ioe1;
- break;
- }
- }
- fcpConnection.handleDisconnect(throwable);
- }
-
- /**
- * Stops the connection handler.
- */
- public void stop() {
- synchronized (this) {
- shouldStop = true;
- }
- }
-
- //
- // PRIVATE METHODS
- //
-
- /**
- * Reads bytes from {@link #remoteInputStream} until ‘\r’ or ‘\n’ are
- * encountered and decodes the read bytes using UTF-8.
- *
- * @return The decoded line
- * @throws IOException
- * if an I/O error occurs
- */
- private String readLine() throws IOException {
- byte[] readBytes = new byte[512];
- int readIndex = 0;
- while (true) {
- int nextByte = remoteInputStream.read();
- if (nextByte == -1) {
- if (readIndex == 0) {
- return null;
- }
- break;
- }
- if (nextByte == 10) {
- if (!ignoreNextLinefeed) {
- break;
- }
- }
- ignoreNextLinefeed = false;
- if (nextByte == 13) {
- ignoreNextLinefeed = true;
- break;
- }
- if (readIndex == readBytes.length) {
- /* recopy & enlarge array */
- byte[] newReadBytes = new byte[readBytes.length * 2];
- System.arraycopy(readBytes, 0, newReadBytes, 0, readBytes.length);
- readBytes = newReadBytes;
- }
- readBytes[readIndex++] = (byte) nextByte;
- }
- ByteBuffer byteBuffer = ByteBuffer.wrap(readBytes, 0, readIndex);
- return Charset.forName("UTF-8").decode(byteBuffer).toString();
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpKeyPair.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Container for an SSK keypair.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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;
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FpcListener.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.EventListener;
-
-/**
- * Interface for objects that want to be notified on certain FCP events.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public interface FcpListener extends EventListener {
-
- /**
- * Notifies a listener that a “NodeHello” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param nodeHello
- * The “NodeHello” message
- */
- public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello);
-
- /**
- * Notifies a listener that a “CloseConnectionDuplicateClientName” message
- * was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param closeConnectionDuplicateClientName
- * The “CloseConnectionDuplicateClientName” message
- */
- public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName);
-
- /**
- * Notifies a listener that a “SSKKeypair” message was received.
- *
- * @param fcpConnection
- * The connection that received themessage
- * @param sskKeypair
- * The “SSKKeypair” message
- */
- public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair);
-
- /**
- * Notifies a listener that a “Peer” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param peer
- * The “Peer” message
- */
- public void receivedPeer(FcpConnection fcpConnection, Peer peer);
-
- /**
- * Notifies a listener that an “EndListPeers” message was received.
- *
- * @param fcpConnection
- * The connection that recevied the message
- * @param endListPeers
- * The “EndListPeers” message
- */
- public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers);
-
- /**
- * Notifies a listener that a “PeerNote” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param peerNote
- * The “PeerNote” message
- */
- public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote);
-
- /**
- * Notifies a listener that an “EndListPeerNotes” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param endListPeerNotes
- * The “EndListPeerNotes” message
- */
- public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes);
-
- /**
- * Notifies a listener that a “PeerRemoved” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param peerRemoved
- * The “PeerRemoved” message
- */
- public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved);
-
- /**
- * Notifies a listener that a “NodeData” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param nodeData
- * The “NodeData” message
- */
- public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData);
-
- /**
- * Notifies a listener that a “TestDDAReply” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param testDDAReply
- * The “TestDDAReply” message
- */
- public void receivedTestDDAReply(FcpConnection fcpConnection, TestDDAReply testDDAReply);
-
- /**
- * Notifies a listener that a “TestDDAComplete” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param testDDAComplete
- * The “TestDDAComplete” message
- */
- public void receivedTestDDAComplete(FcpConnection fcpConnection, TestDDAComplete testDDAComplete);
-
- /**
- * Notifies a listener that a “PersistentGet” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param persistentGet
- * The “PersistentGet” message
- */
- public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet);
-
- /**
- * Notifies a listener that a “PersistentPut” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param persistentPut
- * The “PersistentPut” message
- */
- public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut);
-
- /**
- * Notifies a listener that a “EndListPersistentRequests” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param endListPersistentRequests
- * The “EndListPersistentRequests” message
- */
- public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests);
-
- /**
- * Notifies a listener that a “URIGenerated” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param uriGenerated
- * The “URIGenerated” message
- */
- public void receivedURIGenerated(FcpConnection fcpConnection, URIGenerated uriGenerated);
-
- /**
- * Notifies a listener that a “DataFound” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param dataFound
- * The “DataFound” message
- */
- public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound);
-
- /**
- * Notifies a listener that an “AllData” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param allData
- * The “AllData” message
- */
- public void receivedAllData(FcpConnection fcpConnection, AllData allData);
-
- /**
- * Notifies a listener that a “SimpleProgress” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param simpleProgress
- * The “SimpleProgress” message
- */
- public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress);
-
- /**
- * Notifies a listener that a “StartedCompression” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param startedCompression
- * The “StartedCompression” message
- */
- public void receivedStartedCompression(FcpConnection fcpConnection, StartedCompression startedCompression);
-
- /**
- * Notifies a listener that a “FinishedCompression” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param finishedCompression
- * The “FinishedCompression” message
- */
- public void receivedFinishedCompression(FcpConnection fcpConnection, FinishedCompression finishedCompression);
-
- /**
- * Notifies a listener that an “UnknownPeerNoteType” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param unknownPeerNoteType
- * The “UnknownPeerNoteType” message
- */
- public void receivedUnknownPeerNoteType(FcpConnection fcpConnection, UnknownPeerNoteType unknownPeerNoteType);
-
- /**
- * Notifies a listener that a “UnknownNodeIdentifier” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param unknownNodeIdentifier
- * The “UnknownNodeIdentifier” message
- */
- public void receivedUnknownNodeIdentifier(FcpConnection fcpConnection, UnknownNodeIdentifier unknownNodeIdentifier);
-
- /**
- * Notifies a listener that a “ConfigData” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param configData
- * The “ConfigData” message
- */
- public void receivedConfigData(FcpConnection fcpConnection, ConfigData configData);
-
- /**
- * Notifies a listener that a “GetFailed” message was recevied.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param getFailed
- * The “GetFailed” message
- */
- public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed);
-
- /**
- * Notifies a listener that a “PutFailed” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param putFailed
- * The “PutFailed” message
- */
- public void receivedPutFailed(FcpConnection fcpConnection, PutFailed putFailed);
-
- /**
- * Notifies a listener that an “IdentifierCollision” message was receied.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param identifierCollision
- * The “IdentifierCollision” message
- */
- public void receivedIdentifierCollision(FcpConnection fcpConnection, IdentifierCollision identifierCollision);
-
- /**
- * Notifies a listener that a “PersistentPutDir” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param persistentPutDir
- * The “PersistentPutDir” message
- */
- public void receivedPersistentPutDir(FcpConnection fcpConnection, PersistentPutDir persistentPutDir);
-
- /**
- * Notifies a listener that a “PersistentRequestRemoved” message was
- * received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param persistentRequestRemoved
- * The “PersistentRequestRemoved” message
- */
- public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved);
-
- /**
- * Notifies a listener that a “SubscribedUSKUpdate” message was received.
- *
- * @param fcpConnection
- * The connection that recevied the message
- * @param subscribedUSKUpdate
- * The “SubscribedUSKUpdate” message
- */
- public void receivedSubscribedUSKUpdate(FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate);
-
- /**
- * Notifies a listener that a “PluginInfo” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param pluginInfo
- * The “PluginInfo” message
- */
- public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo);
-
- /**
- * Notifies a listener that an “FCPPluginReply“ message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param fcpPluginReply
- * The “FCPPluginReply” message
- */
- public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply);
-
- /**
- * Notifies a listener that a “PersistentRequestModified” message was
- * received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param persistentRequestModified
- * The “PersistentRequestModified” message
- */
- public void receivedPersistentRequestModified(FcpConnection fcpConnection, PersistentRequestModified persistentRequestModified);
-
- /**
- * Notifies a listener that a “PutSuccessful” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param putSuccessful
- * The “PutSuccessful” message
- */
- public void receivedPutSuccessful(FcpConnection fcpConnection, PutSuccessful putSuccessful);
-
- /**
- * Notifies a listener that a “PutFetchable” message was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param putFetchable
- * The “PutFetchable” message
- */
- public void receivedPutFetchable(FcpConnection fcpConnection, PutFetchable putFetchable);
-
- /**
- * Notifies a listener that a feed was sent to a peer.
- *
- * @param source
- * The connection that received the message
- * @param sentFeed
- * The “SentFeed” message
- */
- public void receivedSentFeed(FcpConnection source, SentFeed sentFeed);
-
- /**
- * Notifies a listener that a bookmark was updated.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param receivedBookmarkFeed
- * The “ReceivedBookmarkFeed” message
- */
- public void receivedBookmarkFeed(FcpConnection fcpConnection, ReceivedBookmarkFeed receivedBookmarkFeed);
-
- /**
- * Notifies a listener that a “ProtocolError” was received.
- *
- * @param fcpConnection
- * The connection that received the message
- * @param protocolError
- * The “ProtocolError” message
- */
- public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError);
-
- /**
- * Notifies a listener that a message has been received. This method is only
- * called if {@link FcpConnection#handleMessage(FcpMessage)} does not
- * recognize the message. Should that ever happen, please file a bug report!
- *
- * @param fcpConnection
- * The connection that received the message
- * @param fcpMessage
- * The message that was received
- */
- public void receivedMessage(FcpConnection fcpConnection, FcpMessage fcpMessage);
-
- /**
- * Notifies a listener that a connection was closed. A closed connection can
- * be reestablished by calling {@link FcpConnection#connect()} on the same
- * object again.
- *
- * @param fcpConnection
- * The connection that was closed.
- * @param throwable
- * The exception that caused the disconnect, or <code>null</code>
- * if there was no exception
- */
- public void connectionClosed(FcpConnection fcpConnection, Throwable throwable);
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpListenerManager.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import net.pterodactylus.util.event.AbstractListenerManager;
-
-/**
- * Manages FCP listeners and event firing.
- *
- * @author David ‘Bombe’ Roden <bombe@pterodactylus.net>
- */
-public class FcpListenerManager extends AbstractListenerManager<FcpConnection, FcpListener> {
-
- /**
- * Creates a new listener manager.
- *
- * @param fcpConnection
- * The source FCP connection
- */
- public FcpListenerManager(FcpConnection fcpConnection) {
- super(fcpConnection);
- }
-
- /**
- * Notifies listeners that a “NodeHello” message was received.
- *
- * @see FcpListener#receivedNodeHello(FcpConnection, NodeHello)
- * @param nodeHello
- * The “NodeHello” message
- */
- public void fireReceivedNodeHello(NodeHello nodeHello) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedNodeHello(getSource(), nodeHello);
- }
- }
-
- /**
- * Notifies listeners that a “CloseConnectionDuplicateClientName” message
- * was received.
- *
- * @see FcpListener#receivedCloseConnectionDuplicateClientName(FcpConnection,
- * CloseConnectionDuplicateClientName)
- * @param closeConnectionDuplicateClientName
- * The “CloseConnectionDuplicateClientName” message
- */
- public void fireReceivedCloseConnectionDuplicateClientName(CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedCloseConnectionDuplicateClientName(getSource(), closeConnectionDuplicateClientName);
- }
- }
-
- /**
- * Notifies listeners that a “SSKKeypair” message was received.
- *
- * @see FcpListener#receivedSSKKeypair(FcpConnection, SSKKeypair)
- * @param sskKeypair
- * The “SSKKeypair” message
- */
- public void fireReceivedSSKKeypair(SSKKeypair sskKeypair) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedSSKKeypair(getSource(), sskKeypair);
- }
- }
-
- /**
- * Notifies listeners that a “Peer” message was received.
- *
- * @see FcpListener#receivedPeer(FcpConnection, Peer)
- * @param peer
- * The “Peer” message
- */
- public void fireReceivedPeer(Peer peer) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPeer(getSource(), peer);
- }
- }
-
- /**
- * Notifies all listeners that an “EndListPeers” message was received.
- *
- * @see FcpListener#receivedEndListPeers(FcpConnection, EndListPeers)
- * @param endListPeers
- * The “EndListPeers” message
- */
- public void fireReceivedEndListPeers(EndListPeers endListPeers) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedEndListPeers(getSource(), endListPeers);
- }
- }
-
- /**
- * Notifies all listeners that a “PeerNote” message was received.
- *
- * @see FcpListener#receivedPeerNote(FcpConnection, PeerNote)
- * @param peerNote
- */
- public void fireReceivedPeerNote(PeerNote peerNote) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPeerNote(getSource(), peerNote);
- }
- }
-
- /**
- * Notifies all listeners that an “EndListPeerNotes” message was received.
- *
- * @see FcpListener#receivedEndListPeerNotes(FcpConnection,
- * EndListPeerNotes)
- * @param endListPeerNotes
- * The “EndListPeerNotes” message
- */
- public void fireReceivedEndListPeerNotes(EndListPeerNotes endListPeerNotes) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedEndListPeerNotes(getSource(), endListPeerNotes);
- }
- }
-
- /**
- * Notifies all listeners that a “PeerRemoved” message was received.
- *
- * @see FcpListener#receivedPeerRemoved(FcpConnection, PeerRemoved)
- * @param peerRemoved
- * The “PeerRemoved” message
- */
- public void fireReceivedPeerRemoved(PeerRemoved peerRemoved) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPeerRemoved(getSource(), peerRemoved);
- }
- }
-
- /**
- * Notifies all listeners that a “NodeData” message was received.
- *
- * @see FcpListener#receivedNodeData(FcpConnection, NodeData)
- * @param nodeData
- * The “NodeData” message
- */
- public void fireReceivedNodeData(NodeData nodeData) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedNodeData(getSource(), nodeData);
- }
- }
-
- /**
- * Notifies all listeners that a “TestDDAReply” message was received.
- *
- * @see FcpListener#receivedTestDDAReply(FcpConnection, TestDDAReply)
- * @param testDDAReply
- * The “TestDDAReply” message
- */
- public void fireReceivedTestDDAReply(TestDDAReply testDDAReply) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedTestDDAReply(getSource(), testDDAReply);
- }
- }
-
- /**
- * Notifies all listeners that a “TestDDAComplete” message was received.
- *
- * @see FcpListener#receivedTestDDAComplete(FcpConnection, TestDDAComplete)
- * @param testDDAComplete
- * The “TestDDAComplete” message
- */
- public void fireReceivedTestDDAComplete(TestDDAComplete testDDAComplete) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedTestDDAComplete(getSource(), testDDAComplete);
- }
- }
-
- /**
- * Notifies all listeners that a “PersistentGet” message was received.
- *
- * @see FcpListener#receivedPersistentGet(FcpConnection, PersistentGet)
- * @param persistentGet
- * The “PersistentGet” message
- */
- public void fireReceivedPersistentGet(PersistentGet persistentGet) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPersistentGet(getSource(), persistentGet);
- }
- }
-
- /**
- * Notifies all listeners that a “PersistentPut” message was received.
- *
- * @see FcpListener#receivedPersistentPut(FcpConnection, PersistentPut)
- * @param persistentPut
- * The “PersistentPut” message
- */
- public void fireReceivedPersistentPut(PersistentPut persistentPut) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPersistentPut(getSource(), persistentPut);
- }
- }
-
- /**
- * Notifies all listeners that a “EndListPersistentRequests” message was
- * received.
- *
- * @see FcpListener#receivedEndListPersistentRequests(FcpConnection,
- * EndListPersistentRequests)
- * @param endListPersistentRequests
- * The “EndListPersistentRequests” message
- */
- public void fireReceivedEndListPersistentRequests(EndListPersistentRequests endListPersistentRequests) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedEndListPersistentRequests(getSource(), endListPersistentRequests);
- }
- }
-
- /**
- * Notifies all listeners that a “URIGenerated” message was received.
- *
- * @see FcpListener#receivedURIGenerated(FcpConnection, URIGenerated)
- * @param uriGenerated
- * The “URIGenerated” message
- */
- public void fireReceivedURIGenerated(URIGenerated uriGenerated) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedURIGenerated(getSource(), uriGenerated);
- }
- }
-
- /**
- * Notifies all listeners that a “DataFound” message was received.
- *
- * @see FcpListener#receivedDataFound(FcpConnection, DataFound)
- * @param dataFound
- * The “DataFound” message
- */
- public void fireReceivedDataFound(DataFound dataFound) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedDataFound(getSource(), dataFound);
- }
- }
-
- /**
- * Notifies all listeners that an “AllData” message was received.
- *
- * @see FcpListener#receivedAllData(FcpConnection, AllData)
- * @param allData
- * The “AllData” message
- */
- public void fireReceivedAllData(AllData allData) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedAllData(getSource(), allData);
- }
- }
-
- /**
- * Notifies all listeners that a “SimpleProgress” message was received.
- *
- * @see FcpListener#receivedSimpleProgress(FcpConnection, SimpleProgress)
- * @param simpleProgress
- * The “SimpleProgress” message
- */
- public void fireReceivedSimpleProgress(SimpleProgress simpleProgress) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedSimpleProgress(getSource(), simpleProgress);
- }
- }
-
- /**
- * Notifies all listeners that a “StartedCompression” message was received.
- *
- * @see FcpListener#receivedStartedCompression(FcpConnection,
- * StartedCompression)
- * @param startedCompression
- * The “StartedCompression” message
- */
- public void fireReceivedStartedCompression(StartedCompression startedCompression) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedStartedCompression(getSource(), startedCompression);
- }
- }
-
- /**
- * Notifies all listeners that a “FinishedCompression” message was received.
- *
- * @see FcpListener#receivedFinishedCompression(FcpConnection,
- * FinishedCompression)
- * @param finishedCompression
- * The “FinishedCompression” message
- */
- public void fireReceivedFinishedCompression(FinishedCompression finishedCompression) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedFinishedCompression(getSource(), finishedCompression);
- }
- }
-
- /**
- * Notifies all listeners that an “UnknownPeerNoteType” message was
- * received.
- *
- * @see FcpListener#receivedUnknownPeerNoteType(FcpConnection,
- * UnknownPeerNoteType)
- * @param unknownPeerNoteType
- * The “UnknownPeerNoteType” message
- */
- public void fireReceivedUnknownPeerNoteType(UnknownPeerNoteType unknownPeerNoteType) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedUnknownPeerNoteType(getSource(), unknownPeerNoteType);
- }
- }
-
- /**
- * Notifies all listeners that an “UnknownNodeIdentifier” message was
- * received.
- *
- * @see FcpListener#receivedUnknownNodeIdentifier(FcpConnection,
- * UnknownNodeIdentifier)
- * @param unknownNodeIdentifier
- * The “UnknownNodeIdentifier” message
- */
- public void fireReceivedUnknownNodeIdentifier(UnknownNodeIdentifier unknownNodeIdentifier) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedUnknownNodeIdentifier(getSource(), unknownNodeIdentifier);
- }
- }
-
- /**
- * Notifies all listeners that a “ConfigData” message was received.
- *
- * @see FcpListener#receivedConfigData(FcpConnection, ConfigData)
- * @param configData
- * The “ConfigData” message
- */
- public void fireReceivedConfigData(ConfigData configData) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedConfigData(getSource(), configData);
- }
- }
-
- /**
- * Notifies all listeners that a “GetFailed” message was received.
- *
- * @see FcpListener#receivedGetFailed(FcpConnection, GetFailed)
- * @param getFailed
- * The “GetFailed” message
- */
- public void fireReceivedGetFailed(GetFailed getFailed) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedGetFailed(getSource(), getFailed);
- }
- }
-
- /**
- * Notifies all listeners that a “PutFailed” message was received.
- *
- * @see FcpListener#receivedPutFailed(FcpConnection, PutFailed)
- * @param putFailed
- * The “PutFailed” message
- */
- public void fireReceivedPutFailed(PutFailed putFailed) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPutFailed(getSource(), putFailed);
- }
- }
-
- /**
- * Notifies all listeners that an “IdentifierCollision” message was
- * received.
- *
- * @see FcpListener#receivedIdentifierCollision(FcpConnection,
- * IdentifierCollision)
- * @param identifierCollision
- * The “IdentifierCollision” message
- */
- public void fireReceivedIdentifierCollision(IdentifierCollision identifierCollision) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedIdentifierCollision(getSource(), identifierCollision);
- }
- }
-
- /**
- * Notifies all listeners that an “PersistentPutDir” message was received.
- *
- * @see FcpListener#receivedPersistentPutDir(FcpConnection,
- * PersistentPutDir)
- * @param persistentPutDir
- * The “PersistentPutDir” message
- */
- public void fireReceivedPersistentPutDir(PersistentPutDir persistentPutDir) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPersistentPutDir(getSource(), persistentPutDir);
- }
- }
-
- /**
- * Notifies all listeners that a “PersistentRequestRemoved” message was
- * received.
- *
- * @see FcpListener#receivedPersistentRequestRemoved(FcpConnection,
- * PersistentRequestRemoved)
- * @param persistentRequestRemoved
- * The “PersistentRequestRemoved” message
- */
- public void fireReceivedPersistentRequestRemoved(PersistentRequestRemoved persistentRequestRemoved) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPersistentRequestRemoved(getSource(), persistentRequestRemoved);
- }
- }
-
- /**
- * Notifies all listeners that a “SubscribedUSKUpdate” message was received.
- *
- * @see FcpListener#receivedSubscribedUSKUpdate(FcpConnection,
- * SubscribedUSKUpdate)
- * @param subscribedUSKUpdate
- * The “SubscribedUSKUpdate” message
- */
- public void fireReceivedSubscribedUSKUpdate(SubscribedUSKUpdate subscribedUSKUpdate) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedSubscribedUSKUpdate(getSource(), subscribedUSKUpdate);
- }
- }
-
- /**
- * Notifies all listeners that a “PluginInfo” message was received.
- *
- * @see FcpListener#receivedPluginInfo(FcpConnection, PluginInfo)
- * @param pluginInfo
- * The “PluginInfo” message
- */
- public void fireReceivedPluginInfo(PluginInfo pluginInfo) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPluginInfo(getSource(), pluginInfo);
- }
- }
-
- /**
- * Notifies all listeners that an “FCPPluginReply” message was received.
- *
- * @see FcpListener#receivedFCPPluginReply(FcpConnection, FCPPluginReply)
- * @param fcpPluginReply
- * The “FCPPluginReply” message
- */
- public void fireReceivedFCPPluginReply(FCPPluginReply fcpPluginReply) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedFCPPluginReply(getSource(), fcpPluginReply);
- }
- }
-
- /**
- * Notifies all listeners that a “PersistentRequestModified” message was
- * received.
- *
- * @see FcpListener#receivedPersistentRequestModified(FcpConnection,
- * PersistentRequestModified)
- * @param persistentRequestModified
- * The “PersistentRequestModified” message
- */
- public void fireReceivedPersistentRequestModified(PersistentRequestModified persistentRequestModified) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPersistentRequestModified(getSource(), persistentRequestModified);
- }
- }
-
- /**
- * Notifies all listeners that a “PutSuccessful” message was received.
- *
- * @see FcpListener#receivedPutSuccessful(FcpConnection, PutSuccessful)
- * @param putSuccessful
- * The “PutSuccessful” message
- */
- public void fireReceivedPutSuccessful(PutSuccessful putSuccessful) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPutSuccessful(getSource(), putSuccessful);
- }
- }
-
- /**
- * Notifies all listeners that a “PutFetchable” message was received.
- *
- * @see FcpListener#receivedPutFetchable(FcpConnection, PutFetchable)
- * @param putFetchable
- * The “PutFetchable” message
- */
- public void fireReceivedPutFetchable(PutFetchable putFetchable) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedPutFetchable(getSource(), putFetchable);
- }
- }
-
- /**
- * Notifies all listeners that a “ProtocolError” message was received.
- *
- * @see FcpListener#receivedProtocolError(FcpConnection, ProtocolError)
- * @param protocolError
- * The “ProtocolError” message
- */
- public void fireReceivedProtocolError(ProtocolError protocolError) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedProtocolError(getSource(), protocolError);
- }
- }
-
- /**
- * Notifies all listeners that a “SentFeed” message was received.
- *
- * @see FcpListener#receivedSentFeed(FcpConnection, SentFeed)
- * @param sentFeed
- * The “SentFeed” message.
- */
- public void fireSentFeed(SentFeed sentFeed) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedSentFeed(getSource(), sentFeed);
- }
- }
-
- /**
- * Notifies all listeners that a “ReceivedBookmarkFeed” message was
- * received.
- *
- * @see FcpListener#receivedBookmarkFeed(FcpConnection,
- * ReceivedBookmarkFeed)
- * @param receivedBookmarkFeed
- * The “ReceivedBookmarkFeed” message
- */
- public void fireReceivedBookmarkFeed(ReceivedBookmarkFeed receivedBookmarkFeed) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedBookmarkFeed(getSource(), receivedBookmarkFeed);
- }
- }
-
- /**
- * Notifies all registered listeners that a message has been received.
- *
- * @see FcpListener#receivedMessage(FcpConnection, FcpMessage)
- * @param fcpMessage
- * The message that was received
- */
- public void fireMessageReceived(FcpMessage fcpMessage) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.receivedMessage(getSource(), fcpMessage);
- }
- }
-
- /**
- * Notifies all listeners that the connection to the node was closed.
- *
- * @param throwable
- * The exception that caused the disconnect, or <code>null</code>
- * if there was no exception
- * @see FcpListener#connectionClosed(FcpConnection, Throwable)
- */
- public void fireConnectionClosed(Throwable throwable) {
- for (FcpListener fcpListener : getListeners()) {
- fcpListener.connectionClosed(getSource(), throwable);
- }
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpMessage.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * An FCP message. FCP messages consist of a name, an arbitrary amount of
- * “fields” (i.e. key-value pairs), a message end marker, and optional payload
- * data that follows the marker.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpMessage implements Iterable<String> {
-
- /** Constant for the linefeed. */
- private static final String LINEFEED = "\r\n";
-
- /** The name of the message. */
- private final String name;
-
- /** The fields of the message. */
- private final Map<String, String> fields = new HashMap<String, String>();
-
- /** The optional payload input stream. */
- private InputStream payloadInputStream;
-
- /**
- * Creates a new FCP message with the given name.
- *
- * @param name
- * The name of the FCP message
- */
- public FcpMessage(String name) {
- this(name, null);
- }
-
- /**
- * Creates a new FCP message with the given name and the given payload input
- * stream. The payload input stream is not read until the message is sent to
- * the node using {@link FcpConnection#sendMessage(FcpMessage)}.
- *
- * @param name
- * The name of the message
- * @param payloadInputStream
- * The payload of the message
- */
- public FcpMessage(String name, InputStream payloadInputStream) {
- this.name = name;
- this.payloadInputStream = payloadInputStream;
- }
-
- /**
- * Returns the name of the message.
- *
- * @return The name of the message
- */
- public String getName() {
- return name;
- }
-
- /**
- * Checks whether this message has a field with the given name.
- *
- * @param field
- * The name of the field to check for
- * @return <code>true</code> if the message has a field with the given name,
- * <code>false</code> otherwise
- */
- public boolean hasField(String field) {
- return fields.containsKey(field);
- }
-
- /**
- * Sets the field with the given name to the given value. If the field
- * already exists in this message it is overwritten.
- *
- * @param field
- * The name of the field
- * @param value
- * The value of the field
- */
- public void setField(String field, String value) {
- if ((field == null) || (value == null)) {
- throw new NullPointerException(((field == null) ? "field " : "value ") + "must not be null");
- }
- fields.put(field, value);
- }
-
- /**
- * Returns the value of the given field.
- *
- * @param field
- * The name of the field
- * @return The value of the field, or <code>null</code> if there is no such
- * field
- */
- public String getField(String field) {
- return fields.get(field);
- }
-
- /**
- * Returns all fields of this message.
- *
- * @return All fields of this message
- */
- public Map<String, String> getFields() {
- return Collections.unmodifiableMap(fields);
- }
-
- /**
- * {@inheritDoc}
- */
- public Iterator<String> iterator() {
- return fields.keySet().iterator();
- }
-
- /**
- * Sets the payload input stream of the message.
- *
- * @param payloadInputStream
- * The payload input stream
- */
- public void setPayloadInputStream(InputStream payloadInputStream) {
- this.payloadInputStream = payloadInputStream;
- }
-
- /**
- * Writes this message to the given output stream. If the message has a
- * payload (i.e. {@link #payloadInputStream} is not <code>null</code>) the
- * payload is written to the given output stream after the message as well.
- * That means that this method can only be called once because on the second
- * invocation the payload input stream could not be read (again).
- *
- * @param outputStream
- * The output stream to write the message to
- * @throws IOException
- * if an I/O error occurs
- */
- public void write(OutputStream outputStream) throws IOException {
- writeLine(outputStream, name);
- for (Entry<String, String> fieldEntry : fields.entrySet()) {
- writeLine(outputStream, fieldEntry.getKey() + "=" + fieldEntry.getValue());
- }
- writeLine(outputStream, "EndMessage");
- outputStream.flush();
- if (payloadInputStream != null) {
- FcpUtils.copy(payloadInputStream, outputStream);
- outputStream.flush();
- }
- }
-
- //
- // PRIVATE METHODS
- //
-
- /**
- * Writes the given line (followed by {@link #LINEFEED} to the given output
- * stream, using UTF-8 as encoding.
- *
- * @param outputStream
- * The output stream to write to
- * @param line
- * The line to write
- * @throws IOException
- * if an I/O error occurs
- */
- private void writeLine(OutputStream outputStream, String line) throws IOException {
- outputStream.write((line + LINEFEED).getBytes("UTF-8"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpTest.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.IOException;
-
-import junit.framework.TestCase;
-
-/**
- * Tests various commands and the FCP connection.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpTest extends TestCase {
-
- /** The FCP connection. */
- private FcpConnection fcpConnection;
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void setUp() throws Exception {
- fcpConnection = new FcpConnection("wing");
- fcpConnection.connect();
- fcpConnection.sendMessage(new ClientHello("FcpTest"));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void tearDown() throws Exception {
- fcpConnection.close();
- }
-
- /**
- * Tests the FCP connection be simply {@link #setUp() setting it up} and
- * {@link #tearDown() tearing it down} again.
- */
- public void testFcpConnection() {
- /* do nothing. */
- }
-
- /**
- * Generates an SSK key pair.
- *
- * @throws IOException
- * if an I/O error occurs
- * @throws InterruptedException
- * if {@link Object#wait()} wakes up spuriously
- */
- public void testGenerateSSK() throws IOException, InterruptedException {
- final SSKKeypair[] keypair = new SSKKeypair[1];
- FcpAdapter fcpAdapter = new FcpAdapter() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
- keypair[0] = sskKeypair;
- synchronized (this) {
- notify();
- }
- }
- };
- fcpConnection.addFcpListener(fcpAdapter);
- synchronized (fcpAdapter) {
- fcpConnection.sendMessage(new GenerateSSK());
- fcpAdapter.wait();
- }
- assertNotNull("ssk keypair", keypair[0]);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpUtils.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.util.StringTokenizer;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Helper class with utility methods for the FCP protocol.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpUtils {
-
- /** Counter for unique identifiers. */
- private static AtomicLong counter = new AtomicLong();
-
- /**
- * Returns a unique identifier.
- *
- * @return A unique identifier
- */
- public static String getUniqueIdentifier() {
- return new StringBuilder().append(System.currentTimeMillis()).append('-').append(counter.getAndIncrement()).toString();
- }
-
- /**
- * Parses an integer field, separated by ‘;’ and returns the parsed values.
- *
- * @param field
- * The field to parse
- * @return An array with the parsed values
- * @throws NumberFormatException
- * if a value can not be converted to a number
- */
- public static int[] decodeMultiIntegerField(String field) throws NumberFormatException {
- StringTokenizer fieldTokens = new StringTokenizer(field, ";");
- int[] result = new int[fieldTokens.countTokens()];
- int counter = 0;
- while (fieldTokens.hasMoreTokens()) {
- String fieldToken = fieldTokens.nextToken();
- result[counter++] = Integer.valueOf(fieldToken);
- }
- return result;
- }
-
- /**
- * Encodes the given integer array into a string, separating the values by
- * ‘;’.
- *
- * @param values
- * The values to encode
- * @return The encoded values
- */
- public static String encodeMultiIntegerField(int[] values) {
- StringBuilder encodedField = new StringBuilder();
- for (int value : values) {
- if (encodedField.length() > 0) {
- encodedField.append(';');
- }
- encodedField.append(value);
- }
- return encodedField.toString();
- }
-
- /**
- * Encodes the given string array into a string, separating the values by
- * ‘;’.
- *
- * @param values
- * The values to encode
- * @return The encoded values
- */
- public static String encodeMultiStringField(String[] values) {
- StringBuilder encodedField = new StringBuilder();
- for (String value : values) {
- if (encodedField.length() > 0) {
- encodedField.append(';');
- }
- encodedField.append(value);
- }
- return encodedField.toString();
- }
-
- /**
- * Tries to parse the given string into an int, returning <code>-1</code> if
- * the string can not be parsed.
- *
- * @param value
- * The string to parse
- * @return The parsed int, or <code>-1</code>
- */
- public static int safeParseInt(String value) {
- return safeParseInt(value, -1);
- }
-
- /**
- * Tries to parse the given string into an int, returning
- * <code>defaultValue</code> if the string can not be parsed.
- *
- * @param value
- * The string to parse
- * @param defaultValue
- * The value to return if the string can not be parsed.
- * @return The parsed int, or <code>defaultValue</code>
- */
- public static int safeParseInt(String value, int defaultValue) {
- try {
- return Integer.valueOf(value);
- } catch (NumberFormatException nfe1) {
- return defaultValue;
- }
- }
-
- /**
- * Tries to parse the given string into an long, returning <code>-1</code>
- * if the string can not be parsed.
- *
- * @param value
- * The string to parse
- * @return The parsed long, or <code>-1</code>
- */
- public static long safeParseLong(String value) {
- return safeParseLong(value, -1);
- }
-
- /**
- * Tries to parse the given string into an long, returning
- * <code>defaultValue</code> if the string can not be parsed.
- *
- * @param value
- * The string to parse
- * @param defaultValue
- * The value to return if the string can not be parsed.
- * @return The parsed long, or <code>defaultValue</code>
- */
- public static long safeParseLong(String value, long defaultValue) {
- try {
- return Integer.valueOf(value);
- } catch (NumberFormatException nfe1) {
- return defaultValue;
- }
- }
-
- /**
- * Closes the given socket.
- *
- * @param socket
- * The socket to close
- */
- public static void close(Socket socket) {
- if (socket != null) {
- try {
- socket.close();
- } catch (IOException ioe1) {
- /* ignore. */
- }
- }
- }
-
- /**
- * Closes the given Closeable.
- *
- * @param closeable
- * The Closeable to close
- */
- public static void close(Closeable closeable) {
- if (closeable != null) {
- try {
- closeable.close();
- } catch (IOException ioe1) {
- /* ignore. */
- }
- }
- }
-
- /**
- * Copies as many bytes as possible (i.e. until {@link InputStream#read()}
- * returns <code>-1</code>) from the source input stream to the destination
- * output stream.
- *
- * @param source
- * The input stream to read from
- * @param destination
- * The output stream to write to
- * @throws IOException
- * if an I/O error occurs
- */
- public static void copy(InputStream source, OutputStream destination) throws IOException {
- copy(source, destination, -1);
- }
-
- /**
- * Copies <code>length</code> bytes from the source input stream to the
- * destination output stream. If <code>length</code> is <code>-1</code> as
- * much bytes as possible will be copied (i.e. until
- * {@link InputStream#read()} returns <code>-1</code> to signal the end of
- * the stream).
- *
- * @param source
- * The input stream to read from
- * @param destination
- * The output stream to write to
- * @param length
- * The number of bytes to copy
- * @throws IOException
- * if an I/O error occurs
- */
- public static void copy(InputStream source, OutputStream destination, long length) throws IOException {
- copy(source, destination, length, 1 << 16);
- }
-
- /**
- * Copies <code>length</code> bytes from the source input stream to the
- * destination output stream. If <code>length</code> is <code>-1</code> as
- * much bytes as possible will be copied (i.e. until
- * {@link InputStream#read()} returns <code>-1</code> to signal the end of
- * the stream).
- *
- * @param source
- * The input stream to read from
- * @param destination
- * The output stream to write to
- * @param length
- * The number of bytes to copy
- * @param bufferSize
- * The buffer size
- * @throws IOException
- * if an I/O error occurs
- */
- public static void copy(InputStream source, OutputStream destination, long length, int bufferSize) throws IOException {
- long remaining = length;
- byte[] buffer = new byte[bufferSize];
- int read = 0;
- while ((remaining == -1) || (remaining > 0)) {
- read = source.read(buffer, 0, ((remaining > bufferSize) || (remaining == -1)) ? bufferSize : (int) remaining);
- if (read == -1) {
- if (length == -1) {
- return;
- }
- throw new EOFException("stream reached eof");
- }
- destination.write(buffer, 0, read);
- remaining -= read;
- }
- }
-
- /**
- * This input stream stores the content of another input stream either in a
- * file or in memory, depending on the length of the input stream.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- public static class TempInputStream extends InputStream {
-
- /** The default maximum lenght for in-memory storage. */
- public static final long MAX_LENGTH_MEMORY = 65536;
-
- /** The temporary file to read from. */
- private final File tempFile;
-
- /** The input stream that reads from the file. */
- private final InputStream fileInputStream;
-
- /** The input stream that reads from memory. */
- private final InputStream memoryInputStream;
-
- /**
- * Creates a new temporary input stream that stores the given input
- * stream in a temporary file.
- *
- * @param originalInputStream
- * The original input stream
- * @throws IOException
- * if an I/O error occurs
- */
- public TempInputStream(InputStream originalInputStream) throws IOException {
- this(originalInputStream, -1);
- }
-
- /**
- * Creates a new temporary input stream that stores the given input
- * stream in memory if it is shorter than {@link #MAX_LENGTH_MEMORY},
- * otherwise it is stored in a file.
- *
- * @param originalInputStream
- * The original input stream
- * @param length
- * The length of the input stream
- * @throws IOException
- * if an I/O error occurs
- */
- public TempInputStream(InputStream originalInputStream, long length) throws IOException {
- this(originalInputStream, length, MAX_LENGTH_MEMORY);
- }
-
- /**
- * Creates a new temporary input stream that stores the given input
- * stream in memory if it is shorter than <code>maxMemoryLength</code>,
- * otherwise it is stored in a file.
- *
- * @param originalInputStream
- * The original input stream
- * @param length
- * The length of the input stream
- * @param maxMemoryLength
- * The maximum length to store in memory
- * @throws IOException
- * if an I/O error occurs
- */
- public TempInputStream(InputStream originalInputStream, long length, long maxMemoryLength) throws IOException {
- if ((length > -1) && (length <= maxMemoryLength)) {
- ByteArrayOutputStream memoryOutputStream = new ByteArrayOutputStream((int) length);
- try {
- FcpUtils.copy(originalInputStream, memoryOutputStream, length, (int) length);
- } finally {
- memoryOutputStream.close();
- }
- tempFile = null;
- fileInputStream = null;
- memoryInputStream = new ByteArrayInputStream(memoryOutputStream.toByteArray());
- } else {
- tempFile = File.createTempFile("temp-", ".bin");
- tempFile.deleteOnExit();
- FileOutputStream fileOutputStream = null;
- try {
- fileOutputStream = new FileOutputStream(tempFile);
- FcpUtils.copy(originalInputStream, fileOutputStream);
- fileInputStream = new FileInputStream(tempFile);
- } finally {
- FcpUtils.close(fileOutputStream);
- }
- memoryInputStream = null;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int available() throws IOException {
- if (memoryInputStream != null) {
- return memoryInputStream.available();
- }
- return fileInputStream.available();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void close() throws IOException {
- if (memoryInputStream != null) {
- memoryInputStream.close();
- return;
- }
- tempFile.delete();
- fileInputStream.close();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public synchronized void mark(int readlimit) {
- if (memoryInputStream != null) {
- memoryInputStream.mark(readlimit);
- return;
- }
- fileInputStream.mark(readlimit);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean markSupported() {
- if (memoryInputStream != null) {
- return memoryInputStream.markSupported();
- }
- return fileInputStream.markSupported();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int read() throws IOException {
- if (memoryInputStream != null) {
- return memoryInputStream.read();
- }
- return fileInputStream.read();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int read(byte[] b) throws IOException {
- if (memoryInputStream != null) {
- return memoryInputStream.read(b);
- }
- return fileInputStream.read(b);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- if (memoryInputStream != null) {
- return memoryInputStream.read(b, off, len);
- }
- return fileInputStream.read(b, off, len);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public synchronized void reset() throws IOException {
- if (memoryInputStream != null) {
- memoryInputStream.reset();
- return;
- }
- fileInputStream.reset();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public long skip(long n) throws IOException {
- if (memoryInputStream != null) {
- return memoryInputStream.skip(n);
- }
- return fileInputStream.skip(n);
- }
-
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FileEntry.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Container class for file entry data.
- *
- * @see ClientPutComplexDir#addFileEntry(FileEntry)
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public abstract class FileEntry {
-
- /** The name of the file. */
- protected final String name;
-
- /** The upload source of the file. */
- protected final UploadFrom uploadFrom;
-
- /**
- * Creates a new file entry with the given name and upload source.
- *
- * @param name
- * The name of the file
- * @param uploadFrom
- * The upload source of the file
- */
- protected FileEntry(String name, UploadFrom uploadFrom) {
- this.name = name;
- this.uploadFrom = uploadFrom;
- }
-
- /**
- * Creates a new file entry for a file that should be transmitted to the
- * node in the payload of the message.
- *
- * @param name
- * The name of the file
- * @param contentType
- * The content type of the file, or <code>null</code> to let the
- * node auto-detect it
- * @param length
- * The length of the file
- * @param dataInputStream
- * The input stream of the file
- * @return A file entry
- */
- public static FileEntry createDirectFileEntry(String name, String contentType, long length, InputStream dataInputStream) {
- return new DirectFileEntry(name, contentType, length, dataInputStream);
- }
-
- /**
- * Creates a new file entry for a file that should be uploaded from disk.
- *
- * @param name
- * The name of the file
- * @param filename
- * The name of the file on disk
- * @param contentType
- * The content type of the file, or <code>null</code> to let the
- * node auto-detect it
- * @param length
- * The length of the file, or <code>-1</code> to not specify a
- * size
- * @return A file entry
- */
- public static FileEntry createDiskFileEntry(String name, String filename, String contentType, long length) {
- return new DiskFileEntry(name, filename, contentType, length);
- }
-
- /**
- * Creates a new file entry for a file that redirects to another URI.
- *
- * @param name
- * The name of the file
- * @param targetURI
- * The target URI of the redirect
- * @return A file entry
- */
- public static FileEntry createRedirectFileEntry(String name, String targetURI) {
- return new RedirectFileEntry(name, targetURI);
- }
-
- /**
- * Returns the fields for this file entry.
- *
- * @return The fields for this file entry
- */
- abstract Map<String, String> getFields();
-
- /**
- * A file entry for a file that should be transmitted in the payload of the
- * {@link ClientPutComplexDir} message.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- static class DirectFileEntry extends FileEntry {
-
- /** The content type of the data. */
- private final String contentType;
-
- /** The length of the data. */
- private final long length;
-
- /** The input stream of the data. */
- private final InputStream inputStream;
-
- /**
- * Creates a new direct file entry with content type auto-detection.
- *
- * @param name
- * The name of the file
- * @param length
- * The length of the file
- * @param inputStream
- * The input stream of the file
- */
- public DirectFileEntry(String name, long length, InputStream inputStream) {
- this(name, null, length, inputStream);
- }
-
- /**
- * Creates a new direct file entry.
- *
- * @param name
- * The name of the file
- * @param contentType
- * The content type of the file, or <code>null</code> to let
- * the node auto-detect it
- * @param length
- * The length of the file
- * @param inputStream
- * The input stream of the file
- */
- public DirectFileEntry(String name, String contentType, long length, InputStream inputStream) {
- super(name, UploadFrom.direct);
- this.contentType = contentType;
- this.length = length;
- this.inputStream = inputStream;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- Map<String, String> getFields() {
- Map<String, String> fields = new HashMap<String, String>();
- fields.put("Name", name);
- fields.put("UploadFrom", String.valueOf(uploadFrom));
- fields.put("DataLength", String.valueOf(length));
- if (contentType != null) {
- fields.put("Metadata.ContentType", contentType);
- }
- return fields;
- }
-
- /**
- * Returns the input stream of the file.
- *
- * @return The input stream of the file
- */
- InputStream getInputStream() {
- return inputStream;
- }
-
- }
-
- /**
- * A file entry for a file that should be uploaded from the disk.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- static class DiskFileEntry extends FileEntry {
-
- /** The name of the on-disk file. */
- private final String filename;
-
- /** The content type of the file. */
- private final String contentType;
-
- /** The length of the file. */
- private final long length;
-
- /**
- * Creates a new disk file entry.
- *
- * @param name
- * The name of the file
- * @param filename
- * The name of the on-disk file
- * @param length
- * The length of the file
- */
- public DiskFileEntry(String name, String filename, long length) {
- this(name, filename, null, length);
- }
-
- /**
- * Creates a new disk file entry.
- *
- * @param name
- * The name of the file
- * @param filename
- * The name of the on-disk file
- * @param contentType
- * The content type of the file, or <code>null</code> to let
- * the node auto-detect it
- * @param length
- * The length of the file
- */
- public DiskFileEntry(String name, String filename, String contentType, long length) {
- super(name, UploadFrom.disk);
- this.filename = filename;
- this.contentType = contentType;
- this.length = length;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- Map<String, String> getFields() {
- Map<String, String> fields = new HashMap<String, String>();
- fields.put("Name", name);
- fields.put("UploadFrom", String.valueOf(uploadFrom));
- fields.put("Filename", filename);
- if (length > -1) {
- fields.put("DataSize", String.valueOf(length));
- }
- if (contentType != null) {
- fields.put("Metadata.ContentType", contentType);
- }
- return fields;
- }
-
- }
-
- /**
- * A file entry for a file that redirects to another URI.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- static class RedirectFileEntry extends FileEntry {
-
- /** The target URI of the redirect. */
- private String targetURI;
-
- /**
- * Creates a new redirect file entry.
- *
- * @param name
- * The name of the file
- * @param targetURI
- * The target URI of the redirect
- */
- public RedirectFileEntry(String name, String targetURI) {
- super(name, UploadFrom.redirect);
- this.targetURI = targetURI;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- Map<String, String> getFields() {
- Map<String, String> fields = new HashMap<String, String>();
- fields.put("Name", name);
- fields.put("UploadFrom", String.valueOf(uploadFrom));
- fields.put("TargetURI", targetURI);
- return fields;
- }
-
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FinishedCompression.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “FinishedCompression” message signals the client that the compression of
- * the request data has been finished.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - GenerateSSK.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “GenerateSSK” message. This message tells the node to generate a new SSK
- * key pair.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - GetConfig.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “GetConfig” command tells the node to send its configuration to the
- * client.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class GetConfig extends FcpMessage {
-
- /**
- * Creates a new “GetConfig” command.
- */
- public GetConfig() {
- super("GetConfig");
- }
-
- /**
- * Sets whether the {@link ConfigData} result message shall include the
- * current values.
- *
- * @param withCurrent
- * <code>true</code> to include current values in the result,
- * <code>false</code> otherwise
- */
- public void setWithCurrent(boolean withCurrent) {
- setField("WithCurrent", String.valueOf(withCurrent));
- }
-
- /**
- * Sets whether the {@link ConfigData} result message shall include the
- * short descriptions.
- *
- * @param withShortDescription
- * <code>true</code> to include the short descriptions in the
- * result, <code>false</code> otherwise
- */
- public void setWithShortDescription(boolean withShortDescription) {
- setField("WithShortDescription", String.valueOf(withShortDescription));
- }
-
- /**
- * Sets whether the {@link ConfigData} result message shall include the long
- * descriptions.
- *
- * @param withLongDescription
- * <code>true</code> to include the long descriptions in the
- * result, <code>false</code> otherwise
- */
- public void setWithLongDescription(boolean withLongDescription) {
- setField("WithLongDescription", String.valueOf(withLongDescription));
- }
-
- /**
- * Sets whether the {@link ConfigData} result message shall include the data
- * types.
- *
- * @param withDataTypes
- * <code>true</code> to include the data types in the result,
- * <code>false</code> otherwise
- */
- public void setWithDataTypes(boolean withDataTypes) {
- setField("WithDataTypes", String.valueOf(withDataTypes));
- }
-
- /**
- * Sets whether the {@link ConfigData} result message shall include the
- * defaults.
- *
- * @param setWithDefaults
- * <code>true</code> to include the defaults in the result,
- * <code>false</code> otherwise
- */
- public void setWithDefaults(boolean setWithDefaults) {
- setField("WithDefaults", String.valueOf(setWithDefaults));
- }
-
- /**
- * Sets whether the {@link ConfigData} result message shall include the sort
- * order.
- *
- * @param withSortOrder
- * <code>true</code> to include the sort order in the result,
- * <code>false</code> otherwise
- */
- public void setWithSortOrder(boolean withSortOrder) {
- setField("WithSortOrder", String.valueOf(withSortOrder));
- }
-
- /**
- * Sets whether the {@link ConfigData} result message shall include the
- * expert flag.
- *
- * @param withExpertFlag
- * <code>true</code> to include the expert flag in the result,
- * <code>false</code> otherwise
- */
- public void setWithExpertFlag(boolean withExpertFlag) {
- setField("WithExpertFlag", String.valueOf(withExpertFlag));
- }
-
- /**
- * Sets whether the {@link ConfigData} result message shall include the
- * force-write flag.
- *
- * @param withForceWriteFlag
- * <code>true</code> to include the force-write flag in the
- * result, <code>false</code> otherwise
- */
- public void setWithForceWriteFlag(boolean withForceWriteFlag) {
- setField("WithForceWriteFlag", String.valueOf(withForceWriteFlag));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - GetFailed.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The “GetFailed” message signals the client that a {@link ClientGet} request
- * has failed. This also means that no further progress messages for that
- * request will be sent.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class GetFailed extends BaseMessage {
-
- /**
- * Creates a new “GetFailed” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- GetFailed(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the code of the error.
- *
- * @return The code of the error, or <code>-1</code> if the error code could
- * not be parsed
- */
- public int getCode() {
- return FcpUtils.safeParseInt(getField("Code"));
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns whether the request is on the global queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on the client-local queue
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
- /**
- * Returns the description of the error code.
- *
- * @return The description of the error code
- */
- public String getCodeDescription() {
- return getField("CodeDescription");
- }
-
- /**
- * Returns the extra description of the error.
- *
- * @return The extra description of the error
- */
- public String getExtraDescription() {
- return getField("ExtraDescription");
- }
-
- /**
- * Returns the short description of the error.
- *
- * @return The short description of the error
- */
- public String getShortCodeDescription() {
- return getField("ShortCodeDescription");
- }
-
- /**
- * Returns the expected data length, if already knows.
- *
- * @return The expected data length, or <code>-1</code> if the length could
- * not be parsed
- */
- public long getExpectedDataLength() {
- return FcpUtils.safeParseLong(getField("ExpectedDataLength"));
- }
-
- /**
- * Returns the expected content type of the request.
- *
- * @return The expected content type
- */
- public String getExpectedMetadataContentType() {
- return getField("ExpectedMetadata.ContentType");
- }
-
- /**
- * Returns whether the expected values (see {@link #getExpectedDataLength()}
- * and {@link #getExpectedMetadataContentType()}) have already been
- * finalized and can be trusted. If the values have not been finalized that
- * can change over time.
- *
- * @return <code>true</code> if the expected values have already been
- * finalized, <code>false</code> otherwise
- */
- public boolean isFinalizedExpected() {
- return Boolean.valueOf(getField("FinalizedExpected"));
- }
-
- /**
- * Returns the URI the request is redirected to (in case of a request for a
- * USK). This is returned so that client applications know that the URI of
- * the key has updated.
- *
- * @return The URI the request was redirected to
- */
- public String getRedirectURI() {
- return getField("RedirectURI");
- }
-
- /**
- * Returns whether the request failed fatally. If a request fails fatally it
- * can never complete, even with inifinite retries.
- *
- * @return <code>true</code> if the request failed fatally,
- * <code>false</code> otherwise
- */
- public boolean isFatal() {
- return Boolean.valueOf(getField("Fatal"));
- }
-
- /**
- * Returns a list of complex error codes with the message. Use
- * {@link #getComplexErrorDescription(int)} and
- * {@link #getComplexErrorCount(int)} to get details.
- *
- * @return A list of complex error codes
- */
- public int[] getComplexErrorCodes() {
- Map<String, String> allFields = getFields();
- List<Integer> errorCodeList = new ArrayList<Integer>();
- for (Entry<String, String> field : allFields.entrySet()) {
- String fieldKey = field.getKey();
- if (fieldKey.startsWith("Errors.")) {
- int nextDot = fieldKey.indexOf('.', 7);
- if (nextDot > -1) {
- int errorCode = FcpUtils.safeParseInt(fieldKey.substring(7, nextDot));
- if (errorCode != -1) {
- errorCodeList.add(errorCode);
- }
- }
- }
- }
- int[] errorCodes = new int[errorCodeList.size()];
- int errorIndex = 0;
- for (int errorCode : errorCodeList) {
- errorCodes[errorIndex++] = errorCode;
- }
- return errorCodes;
- }
-
- /**
- * Returns the description of the complex error. You should only hand it
- * error codes you got from {@link #getComplexErrorCodes()}!
- *
- * @param errorCode
- * The error code
- * @return The description of the complex error
- */
- public String getComplexErrorDescription(int errorCode) {
- return getField("Errors." + errorCode + ".Description");
- }
-
- /**
- * Returns the count of the complex error. You should only hand it error
- * codes you got from {@link #getComplexErrorCodes()}!
- *
- * @param errorCode
- * The error code
- * @return The count of the complex error, or <code>-1</code> if the count
- * could not be parsed
- */
- public int getComplexErrorCount(int errorCode) {
- return FcpUtils.safeParseInt(getField("Errors." + errorCode + ".Count"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - GetNode.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “GetNode” command returns the darknet or opennet noderef of the node,
- * optionally including private and volatile data.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class GetNode extends FcpMessage {
-
- /**
- * Creates a “GetNode” command that returns the darknet noderef of the node.
- */
- public GetNode() {
- this(null, null, null);
- }
-
- /**
- * Creates a “GetNode” command that returns the request noderef of the node,
- * including private and volatile data, if requested. If any of the Boolean
- * parameters are <code>null</code> the parameter is ignored and the node’s
- * default value is used.
- *
- * @param giveOpennetRef
- * <code>true</code> to request the opennet noderef,
- * <code>false</code> for darknet
- * @param withPrivate
- * <code>true</code> to include private data in the noderef
- * @param withVolatile
- * <code>true</code> to include volatile data in the noderef
- */
- public GetNode(Boolean giveOpennetRef, Boolean withPrivate, Boolean withVolatile) {
- super("GetNode");
- if (giveOpennetRef != null) {
- setField("GiveOpennetRef", String.valueOf(giveOpennetRef));
- }
- if (withPrivate != null) {
- setField("WithPrivate", String.valueOf(withPrivate));
- }
- if (withVolatile != null) {
- setField("WithVolatile", String.valueOf(withVolatile));
- }
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - GetPluginInfo.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “GetPluginInfo” message requests information about a plugin from the
- * node, which will response with a {@link PluginInfo} message.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class GetPluginInfo extends FcpMessage {
-
- /**
- * Creates a new “GetPluginInfo” message.
- *
- * @param pluginName
- * The name of the plugin
- * @param identifier
- * The identifier of the request
- */
- public GetPluginInfo(String pluginName, String identifier) {
- super("GetPluginInfo");
- setField("PluginName", pluginName);
- setField("Identifier", identifier);
- }
-
- /**
- * Sets whether detailed information about the plugin is wanted.
- *
- * @param detailed
- * <code>true</code> to request detailed information about the
- * plugin, <code>false</code> otherwise
- */
- public void setDetailed(boolean detailed) {
- setField("Detailed", String.valueOf(detailed));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - GetRequestStatus.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “GetRequestStatus” message is used request status information about a
- * running request. It is also the only way to trigger a download of a persisted
- * completed {@link ClientGet} with a return type of {@link ReturnType#direct}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class GetRequestStatus extends FcpMessage {
-
- /**
- * Creates a new “GetRequestStatus” message.
- *
- * @param identifier
- * The identifier of the request
- */
- public GetRequestStatus(String identifier) {
- super("GetRequestStatus");
- setField("Identifier", identifier);
- }
-
- /**
- * Sets whether the request is on the global queue.
- *
- * @param global
- * <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on the client-local queue
- */
- public void setGlobal(boolean global) {
- setField("Global", String.valueOf(global));
- }
-
- /**
- * Sets whether the omit the transmission of the request data in a
- * {@link AllData} message.
- *
- * @param onlyData
- * <code>true</code> to skip transmission of data,
- * <code>false</code> to download data
- */
- public void setOnlyData(boolean onlyData) {
- setField("OnlyData", String.valueOf(onlyData));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - IdentifierCollision.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “IdentifierCollision” message signals the client that the identifier
- * chosen for a request is already existing.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class IdentifierCollision extends BaseMessage {
-
- /**
- * Creates a new “IdentifierCollision” message that wraps the received
- * message.
- *
- * @param receivedMessage
- * The received message
- */
- IdentifierCollision(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns whether the request is on the global queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on the client-local queue
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ListPeer.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ListPeer” request asks the node about the details of a given peer.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ListPeer extends FcpMessage {
-
- /**
- * Creates a new “ListPeer” request that returns information about the node
- * specified by <code>nodeIdentifier</code>. <code>nodeIdentifier</code> can
- * be of several formats: The node’s name, its identity, or its IP address
- * and port (connection with a ‘:’).
- *
- * @param nodeIdentifier
- * The identifier of the node to get details about
- */
- public ListPeer(String nodeIdentifier) {
- super("ListPeer");
- setField("NodeIdentifier", nodeIdentifier);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ListPeerNotes.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ListPeerNodes” request tells the node to list all notes that have been
- * entered for a node. Note that notes are only supported for darknet nodes.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ListPeers.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ListPeer” requests asks the node for a list of all peers it has.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ListPeers extends FcpMessage {
-
- /**
- * Creates a new “ListPeers” request that only includes basic data of the
- * peers.
- *
- * @param identifier
- * The identifier of the request
- */
- public ListPeers(String identifier) {
- this(identifier, false, false);
- }
-
- /**
- * Creates a new “ListPeers” request that includes wanted data of the peers.
- *
- * @param identifier
- * The identifier of the request
- * @param withMetadata
- * If <code>true</code> metadata of the peers is included in the
- * reply
- * @param withVolatile
- * if <code>true</code> volatile data of the peers is included in
- * the reply
- */
- public ListPeers(String identifier, boolean withMetadata, boolean withVolatile) {
- super("ListPeers");
- setField("Identifier", identifier);
- setField("WithMetadata", String.valueOf(withMetadata));
- setField("WithVolatile", String.valueOf(withVolatile));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ListPersistentRequests.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Command to tell the node to list all persistent requests from the current
- * queue, which is either the global queue or the client-local queue, depending
- * on your {@link WatchGlobal} status.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ListPersistentRequests extends FcpMessage {
-
- /**
- * Creates a new “ListPersistentRequests” command that lists all persistent
- * requests in the current queue.
- */
- public ListPersistentRequests() {
- super("ListPersistentRequests");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ModifyConfig.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ModifyConfig” message is used to change the node’s configuration.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ModifyPeer.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ModifyPeer” request lets you modify certain properties of a peer.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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));
- }
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ModifyPeerNote.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ModifyPeerNote” command modifies a peer note.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ModifyPersistentRequest.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “ModifyPersistentRequest” is used to modify certain properties of a
- * persistent request while it is running.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ModifyPersistentRequest extends FcpMessage {
-
- /**
- * Creates a new “ModifyPersistentRequest” that changes the specified
- * request.
- *
- * @param requestIdentifier
- * The identifier of the request
- * @param global
- * <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on the client-local queue
- */
- public ModifyPersistentRequest(String requestIdentifier, boolean global) {
- super("ModifyPersistentRequest");
- setField("Identifier", requestIdentifier);
- setField("Global", String.valueOf(global));
- }
-
- /**
- * Sets the new client token of the request.
- *
- * @param newClientToken
- * The new client token of the request
- */
- public void setClientToken(String newClientToken) {
- setField("ClientToken", newClientToken);
- }
-
- /**
- * Sets the new priority of the request.
- *
- * @param newPriority
- * The new priority of the request
- */
- public void setPriority(Priority newPriority) {
- setField("PriorityClass", String.valueOf(newPriority));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - NodeData.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “NodeData” contains the noderef of the node, along with additional data.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class NodeData extends BaseMessage {
-
- /** The noderef of the node. */
- private final NodeRef nodeRef;
-
- /**
- * Creates a new “NodeData” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- NodeData(FcpMessage receivedMessage) {
- super(receivedMessage);
- nodeRef = new NodeRef(receivedMessage);
- }
-
- /**
- * Returns the noderef of the node.
- *
- * @return The noderef of the node
- */
- public NodeRef getNodeRef() {
- return nodeRef;
- }
-
- /**
- * Returns the last good version, i.e. the oldest version the node will
- * connect to.
- *
- * @return The last good version
- */
- public Version getLastGoodVersion() {
- return nodeRef.getLastGoodVersion();
- }
-
- /**
- * Returns the signature of the noderef.
- *
- * @return The signature of the noderef
- */
- public String getSignature() {
- return nodeRef.getSignature();
- }
-
- /**
- * Returns whether the noderef is the opennet noderef of the node
- *
- * @return <code>true</code> if the noderef is the opennet noderef of the
- * node, <code>false</code> otherwise
- */
- public boolean isOpennet() {
- return nodeRef.isOpennet();
- }
-
- /**
- * Returns the identity of the node
- *
- * @return The identity of the node
- */
- public String getIdentity() {
- return nodeRef.getIdentity();
- }
-
- /**
- * Returns the name of the node.
- *
- * @return The name of the node
- */
- public String getMyName() {
- return nodeRef.getMyName();
- }
-
- /**
- * Returns the version of the node.
- *
- * @return The version of the node
- */
- public Version getVersion() {
- return nodeRef.getVersion();
- }
-
- /**
- * Returns IP addresses and port number of the node.
- *
- * @return The IP addresses and port numbers of the node
- */
- public String getPhysicalUDP() {
- return nodeRef.getPhysicalUDP();
- }
-
- /**
- * Returns the ARK of the node.
- *
- * @return The ARK of the node
- */
- public ARK getARK() {
- return nodeRef.getARK();
- }
-
- /**
- * Returns the public key of the node.
- *
- * @return The public key of the node
- */
- public String getDSAPublicKey() {
- return nodeRef.getDSAPublicKey();
- }
-
- /**
- * Returns the private key of the node.
- *
- * @return The private key of the node
- */
- public String getDSKPrivateKey() {
- return getField("dsaPrivKey.x");
- }
-
- /**
- * Returns the DSA group of the node.
- *
- * @return The DSA group of the node
- */
- public DSAGroup getDSAGroup() {
- return nodeRef.getDSAGroup();
- }
-
- /**
- * Returns the negotiation types supported by the node.
- *
- * @return The node’s supported negotiation types
- */
- public int[] getNegotiationTypes() {
- return nodeRef.getNegotiationTypes();
- }
-
- /**
- * Returns one of the volatile fields from the message. The given field name
- * is prepended with “volatile.” so if you want to get the value of the
- * field with the name “volatile.freeJavaMemory” you only need to specify
- * “freeJavaMemory”.
- *
- * @param field
- * The name of the field
- * @return The value of the field, or <code>null</code> if there is no such
- * field
- */
- public String getVolatile(String field) {
- return getField("volatile." + field);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - NodeHello.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Some convenience methods for parsing a “NodeHello” message from the node.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class NodeHello extends BaseMessage {
-
- /**
- * Createa a new “NodeHello” message that wraps the received message.
- *
- * @param receivedMessage
- * The received FCP message
- */
- NodeHello(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the build of the node. This may not be a number but also a string
- * like “@custom@” in case you built the node yourself.
- *
- * @return The build of the node
- */
- public String getBuild() {
- return getField("Build");
- }
-
- /**
- * Returns the build number of the node. This may not be a number but also a
- * string like “@custom@” in case you built the node yourself.
- *
- * @return The build number of the node, or <code>-1</code> if the build
- * number could not be determined
- */
- public int getBuildNumber() {
- return FcpUtils.safeParseInt(getBuild());
- }
-
- /**
- * Returns the number of compression codecs.
- *
- * @return The number of compression codecs
- */
- public String getCompressionCodecs() {
- return getField("CompressionCodecs");
- }
-
- /**
- * Returns the number of compression codecs.
- *
- * @return The number of compression codecs, or <code>-1</code> if the
- * number of compression codecs could not be determined
- */
- public int getCompressionCodecsNumber() {
- return FcpUtils.safeParseInt(getCompressionCodecs());
- }
-
- /**
- * Returns the unique connection identifier.
- *
- * @return The connection identifier
- */
- public String getConnectionIdentifier() {
- return getField("ConnectionIdentifier");
- }
-
- /**
- * Returns the build of the external library file.
- *
- * @return The build of the external library file
- */
- public String getExtBuild() {
- return getField("ExtBuild");
- }
-
- /**
- * Returns the build number of the external library file.
- *
- * @return The build number of the external library file, or <code>-1</code>
- * if the build number could not be determined
- */
- public int getExtBuildNumber() {
- return FcpUtils.safeParseInt(getExtBuild());
- }
-
- /**
- * Returns the revision of the external library file.
- *
- * @return The revision of the external library file
- */
- public String getExtRevision() {
- return getField("ExtRevision");
- }
-
- /**
- * Returns the revision number of the external library file.
- *
- * @return The revision number of the external library file, or
- * <code>-1</code> if the revision number could not be determined
- */
- public int getExtRevisionNumber() {
- return FcpUtils.safeParseInt(getExtRevision());
- }
-
- /**
- * Returns the FCP version the node speaks.
- *
- * @return The FCP version the node speaks
- */
- public String getFCPVersion() {
- return getField("FCPVersion");
- }
-
- /**
- * Returns the make of the node, e.g. “Fred” (freenet reference
- * implementation).
- *
- * @return The make of the node
- */
- public String getNode() {
- return getField("Node");
- }
-
- /**
- * Returns the language of the node as 2-letter code, e.g. “en” or “de”.
- *
- * @return The language of the node
- */
- public String getNodeLanguage() {
- return getField("NodeLanguage");
- }
-
- /**
- * Returns the revision of the node.
- *
- * @return The revision of the node
- */
- public String getRevision() {
- return getField("Revision");
- }
-
- /**
- * Returns the revision number of the node.
- *
- * @return The revision number of the node, or <code>-1</code> if the
- * revision number coult not be determined
- */
- public int getRevisionNumber() {
- return FcpUtils.safeParseInt(getRevision());
- }
-
- /**
- * Returns whether the node is currently is testnet mode.
- *
- * @return <code>true</code> if the node is currently in testnet mode,
- * <code>false</code> otherwise
- */
- public boolean getTestnet() {
- return Boolean.valueOf(getField("Testnet"));
- }
-
- /**
- * Returns the version of the node.
- *
- * @return The version of the node
- */
- public String getVersion() {
- return getField("Version");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - NodeRef.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A reference for a node. The noderef contains all data that is necessary to
- * establish a trusted and secure connection to the node.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class NodeRef {
-
- /** The identity of the node. */
- private String identity;
-
- /** Whether the node is an opennet peer. */
- private boolean opennet;
-
- /** The name of the node. */
- private String name;
-
- /** The location of the node. */
- private double location;
-
- /** The IP addresses and ports of the node. */
- private String physicalUDP;
-
- /** The ARK of the node. */
- private ARK ark;
-
- /** The public DSA key of the node. */
- private String dsaPublicKey;
-
- /** The DSA group of the node. */
- private DSAGroup dsaGroup;
-
- /** The node’s supported negotiation types. */
- private int[] negotiationTypes;
-
- /** The version of the node. */
- private Version version;
-
- /** The oldest version the node will connect to. */
- private Version lastGoodVersion;
-
- /** Whether the node is a testnet node. */
- private boolean testnet;
-
- /** The signature of the reference. */
- private String signature;
-
- /**
- * Creates a new, empty noderef.
- */
- public NodeRef() {
- /* intentionally left blank. */
- }
-
- /**
- * Creates a new noderef that is initialized with fields from the given
- * message.
- *
- * @param fromMessage
- * The message to get initial values for the noderef from
- */
- public NodeRef(FcpMessage fromMessage) {
- identity = fromMessage.getField("identity");
- opennet = Boolean.valueOf(fromMessage.getField("opennet"));
- name = fromMessage.getField("myName");
- if (fromMessage.hasField("location")) {
- location = Double.valueOf(fromMessage.getField("location"));
- }
- physicalUDP = fromMessage.getField("physical.udp");
- ark = new ARK(fromMessage.getField("ark.pubURI"), fromMessage.getField("ark.privURI"), fromMessage.getField("ark.number"));
- dsaPublicKey = fromMessage.getField("dsaPubKey.y");
- dsaGroup = new DSAGroup(fromMessage.getField("dsaGroup.b"), fromMessage.getField("dsaGroup.p"), fromMessage.getField("dsaGroup.q"));
- negotiationTypes = FcpUtils.decodeMultiIntegerField(fromMessage.getField("auth.negTypes"));
- version = new Version(fromMessage.getField("version"));
- lastGoodVersion = new Version(fromMessage.getField("lastGoodVersion"));
- testnet = Boolean.valueOf(fromMessage.getField("testnet"));
- signature = fromMessage.getField("sig");
- }
-
- /**
- * Returns the identity of the node.
- *
- * @return The identity of the node
- */
- public String getIdentity() {
- return identity;
- }
-
- /**
- * Sets the identity of the node.
- *
- * @param identity
- * The identity of the node
- */
- public void setIdentity(String identity) {
- this.identity = identity;
- }
-
- /**
- * Returns whether the node is an opennet peer.
- *
- * @return <code>true</code> if the node is an opennet peer,
- * <code>false</code> otherwise
- */
- public boolean isOpennet() {
- return opennet;
- }
-
- /**
- * Sets whether the node is an opennet peer.
- *
- * @param opennet
- * <code>true</code> if the node is an opennet peer,
- * <code>false</code> otherwise
- */
- public void setOpennet(boolean opennet) {
- this.opennet = opennet;
- }
-
- /**
- * Returns the name of the node. If the node is an opennet peer, it will not
- * have a name!
- *
- * @return The name of the node, or <code>null</code> if the node is an
- * opennet peer
- */
- public String getMyName() {
- return name;
- }
-
- /**
- * Sets the name of the peer.
- *
- * @param name
- * The name of the peer
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Returns the location of the node.
- *
- * @return The location of the node
- */
- public double getLocation() {
- return location;
- }
-
- /**
- * Sets the location of the node
- *
- * @param location
- * The location of the node
- */
- public void setLocation(double location) {
- this.location = location;
- }
-
- /**
- * Returns the IP addresses and port numbers of the node.
- *
- * @return The IP addresses and port numbers of the node
- */
- public String getPhysicalUDP() {
- return physicalUDP;
- }
-
- /**
- * Sets the IP addresses and port numbers of the node.
- *
- * @param physicalUDP
- * The IP addresses and port numbers of the node
- */
- public void setPhysicalUDP(String physicalUDP) {
- this.physicalUDP = physicalUDP;
- }
-
- /**
- * Returns the ARK of the node.
- *
- * @return The ARK of the node
- */
- public ARK getARK() {
- return ark;
- }
-
- /**
- * Sets the ARK of the node.
- *
- * @param ark
- * The ARK of the node
- */
- public void setARK(ARK ark) {
- this.ark = ark;
- }
-
- /**
- * Returns the public DSA key of the node.
- *
- * @return The public DSA key of the node
- */
- public String getDSAPublicKey() {
- return dsaPublicKey;
- }
-
- /**
- * Sets the public DSA key of the node.
- *
- * @param dsaPublicKey
- * The public DSA key of the node
- */
- public void setDSAPublicKey(String dsaPublicKey) {
- this.dsaPublicKey = dsaPublicKey;
- }
-
- /**
- * Returns the DSA group of the node.
- *
- * @return The DSA group of the node
- */
- public DSAGroup getDSAGroup() {
- return dsaGroup;
- }
-
- /**
- * Sets the DSA group of the node.
- *
- * @param dsaGroup
- * The DSA group of the node
- */
- public void setDSAGroup(DSAGroup dsaGroup) {
- this.dsaGroup = dsaGroup;
- }
-
- /**
- * Returns the negotiation types supported by the node.
- *
- * @return The node’s supported negotiation types
- */
- public int[] getNegotiationTypes() {
- return negotiationTypes;
- }
-
- /**
- * Sets the negotiation types supported by the node.
- *
- * @param negotiationTypes
- * The node’s supported negotiation types
- */
- public void setNegotiationTypes(int[] negotiationTypes) {
- this.negotiationTypes = negotiationTypes;
- }
-
- /**
- * Returns the version of the node.
- *
- * @return The version of the node
- */
- public Version getVersion() {
- return version;
- }
-
- /**
- * Sets the version of the node.
- *
- * @param version
- * The version of the node
- */
- public void setVersion(Version version) {
- this.version = version;
- }
-
- /**
- * Returns the last good version of the node.
- *
- * @return The oldest version the node will connect to
- */
- public Version getLastGoodVersion() {
- return lastGoodVersion;
- }
-
- /**
- * Sets the last good version of the node.
- *
- * @param lastGoodVersion
- * The oldest version the node will connect to
- */
- public void setLastGoodVersion(Version lastGoodVersion) {
- this.lastGoodVersion = lastGoodVersion;
- }
-
- /**
- * Returns whether the node is a testnet node.
- *
- * @return <code>true</code> if the node is a testnet node,
- * <code>false</code> otherwise
- */
- public boolean isTestnet() {
- return testnet;
- }
-
- /**
- * Sets whether this node is a testnet node.
- *
- * @param testnet
- * <code>true</code> if the node is a testnet node,
- * <code>false</code> otherwise
- */
- public void setTestnet(boolean testnet) {
- this.testnet = testnet;
- }
-
- /**
- * Returns the signature of the noderef.
- *
- * @return The signature of the noderef
- */
- public String getSignature() {
- return signature;
- }
-
- /**
- * Sets the signature of the noderef.
- *
- * @param signature
- * The signature of the noderef
- */
- public void setSignature(String signature) {
- this.signature = signature;
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - Peer.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The “Peer” reply by the node contains information about a peer.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class Peer extends BaseMessage {
-
- /**
- * Creates a new “Peer” reply from the received message.
- *
- * @param receivedMessage
- * The received message
- */
- Peer(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns a collection of fields as a node reference.
- *
- * @return The node reference contained within this message
- */
- public NodeRef getNodeRef() {
- NodeRef nodeRef = new NodeRef();
- nodeRef.setARK(getARK());
- nodeRef.setDSAGroup(getDSAGroup());
- nodeRef.setDSAPublicKey(getDSAPublicKey());
- nodeRef.setIdentity(getIdentity());
- nodeRef.setLastGoodVersion(getLastGoodVersion());
- nodeRef.setLocation(getLocation());
- nodeRef.setName(getMyName());
- nodeRef.setNegotiationTypes(getNegotiationTypes());
- nodeRef.setOpennet(isOpennet());
- nodeRef.setPhysicalUDP(getPhysicalUDP());
- nodeRef.setVersion(getVersion());
- return nodeRef;
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the “physical.udp” line from the message. It contains all IP
- * addresses and port numbers of the peer.
- *
- * @return The IP addresses and port numbers of the peer
- */
- public String getPhysicalUDP() {
- return getField("physical.udp");
- }
-
- /**
- * Returns whether the listed peer is an opennet peer.
- *
- * @return <code>true</code> if the peer is an opennet peer,
- * <code>false</code> if the peer is a darknet peer
- */
- public boolean isOpennet() {
- return Boolean.valueOf(getField("opennet"));
- }
-
- /**
- * Returns whether this peer is a seed.
- *
- * @return <code>true</code> if the peer is a seed, <code>false</code>
- * otherwise
- */
- public boolean isSeed() {
- return Boolean.valueOf(getField("seed"));
- }
-
- /**
- * Returns the “y” part of the peer’s public DSA key.
- *
- * @return The public DSA key
- */
- public String getDSAPublicKey() {
- return getField("dsaPubKey.y");
- }
-
- /**
- * Returns the DSA group of the peer.
- *
- * @return The DSA group of the peer
- */
- public DSAGroup getDSAGroup() {
- return new DSAGroup(getField("dsaGroup.g"), getField("dsaGroup.p"), getField("dsaGroup.q"));
- }
-
- /**
- * Returns the last good version of the peer, i.e. the oldest version the
- * peer will connect to.
- *
- * @return The last good version of the peer
- */
- public Version getLastGoodVersion() {
- return new Version(getField("lastGoodVersion"));
- }
-
- /**
- * Returns the ARK of the peer.
- *
- * @return The ARK of the peer
- */
- public ARK getARK() {
- return new ARK(getField("ark.pubURI"), getField("ark.number"));
- }
-
- /**
- * Returns the identity of the peer.
- *
- * @return The identity of the peer
- */
- public String getIdentity() {
- return getField("identity");
- }
-
- /**
- * Returns the name of the peer. If the peer is not a darknet peer it will
- * have no name.
- *
- * @return The name of the peer, or <code>null</code> if the peer is an
- * opennet peer
- */
- public String getMyName() {
- return getField("myName");
- }
-
- /**
- * Returns the location of the peer.
- *
- * @return The location of the peer
- * @throws NumberFormatException
- * if the field can not be parsed
- */
- public double getLocation() throws NumberFormatException {
- return Double.valueOf(getField("location"));
- }
-
- /**
- * Returns whether the peer is a testnet node.
- *
- * @return <code>true</code> if the peer is a testnet node,
- * <code>false</code> otherwise
- */
- public boolean isTestnet() {
- return Boolean.valueOf("testnet");
- }
-
- /**
- * Returns the version of the peer.
- *
- * @return The version of the peer
- */
- public Version getVersion() {
- return new Version(getField("version"));
- }
-
- /**
- * Returns the negotiation types the peer supports.
- *
- * @return The supported negotiation types
- */
- public int[] getNegotiationTypes() {
- return FcpUtils.decodeMultiIntegerField(getField("auth.negTypes"));
- }
-
- /**
- * Returns all volatile fields from the message.
- *
- * @return All volatile files
- */
- public Map<String, String> getVolatileFields() {
- Map<String, String> volatileFields = new HashMap<String, String>();
- for (Entry<String, String> field : getFields().entrySet()) {
- if (field.getKey().startsWith("volatile.")) {
- volatileFields.put(field.getKey(), field.getValue());
- }
- }
- return Collections.unmodifiableMap(volatileFields);
- }
-
- /**
- * Returns one of the volatile fields from the message. The given field name
- * is prepended with “volatile.” so if you want to get the value of the
- * field with the name “volatile.status” you only need to specify “status”.
- *
- * @param field
- * The name of the field
- * @return The value of the field, or <code>null</code> if there is no such
- * field
- */
- public String getVolatile(String field) {
- return getField("volatile." + field);
- }
-
- /**
- * Returns all metadata fields from the message.
- *
- * @return All volatile files
- */
- public Map<String, String> getMetadataFields() {
- Map<String, String> metadataFields = new HashMap<String, String>();
- for (Entry<String, String> field : getFields().entrySet()) {
- if (field.getKey().startsWith("metadata.")) {
- metadataFields.put(field.getKey(), field.getValue());
- }
- }
- return Collections.unmodifiableMap(metadataFields);
- }
-
- /**
- * Returns one of the metadata fields from the message. The given field name
- * is prepended with “metadata.” so if you want to get the value of the
- * field with the name “metadata.timeLastRoutable” you only need to specify
- * “timeLastRoutable”.
- *
- * @param field
- * The name of the field
- * @return The value of the field, or <code>null</code> if there is no such
- * field
- */
- public String getMetadata(String field) {
- return getField("metadata." + field);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PeerNote.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PeerNote” message contains a private note that has been entered for a
- * darknet peer.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PeerNote extends BaseMessage {
-
- /** The type for base64 encoded peer notes. */
- public static final int TYPE_PRIVATE_PEER_NOTE = 1;
-
- /**
- * Creates a “PeerNote” message that wraps the recevied message.
- *
- * @param receivedMessage
- * The received message
- */
- PeerNote(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the node this note belongs to.
- *
- * @return The note’s node’s identifier
- */
- public String getNodeIdentifier() {
- return getField("NodeIdentifier");
- }
-
- /**
- * Returns the base64-encoded note text.
- *
- * @return The note text
- */
- public String getNoteText() {
- return getField("NoteText");
- }
-
- /**
- * Returns the type of the peer note.
- *
- * @return The type of the peer note, or <code>-1</code> if the type can not
- * be parsed
- */
- public int getPeerNoteType() {
- return FcpUtils.safeParseInt(getField("PeerNoteType"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PeerRemoved.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “PeerRemoved” message is sent by the node when a peer has been removed.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - Persistence.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Convenience class for persistence values.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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;
-
-}
+++ /dev/null
-/*
- * jFCPlib - PersistentGet.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PersistentGet” message is sent to the client to inform it about a
- * persistent download, either in the client-local queue or in the global queue.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PersistentGet extends BaseMessage {
-
- /**
- * Creates a new “PersistentGet” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- PersistentGet(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the URI of the request.
- *
- * @return The URI of the request
- */
- public String getURI() {
- return getField("URI");
- }
-
- /**
- * Returns the verbosity of the request.
- *
- * @return The verbosity of the request
- */
- public Verbosity getVerbosity() {
- return Verbosity.valueOf(getField("Verbosity"));
- }
-
- /**
- * Returns the return type of the request.
- *
- * @return The return type of the request
- */
- public ReturnType getReturnType() {
- try {
- return ReturnType.valueOf(getField("ReturnType"));
- } catch (IllegalArgumentException iae1) {
- return ReturnType.unknown;
- }
- }
-
- /**
- * Returns the name of the file the data is downloaded to. This field will
- * only be set if {@link #getReturnType()} is {@link ReturnType#disk}.
- *
- * @return The name of the file the data is downloaded to
- */
- public String getFilename() {
- return getField("Filename");
- }
-
- /**
- * Returns the name of the temporary file. This field will only be set if
- * {@link #getReturnType()} is {@link ReturnType#disk}.
- *
- * @return The name of the temporary file
- */
- public String getTempFilename() {
- return getField("TempFilename");
- }
-
- /**
- * Returns the client token of the request.
- *
- * @return The client token of the request
- */
- public String getClientToken() {
- return getField("ClientToken");
- }
-
- /**
- * Returns the priority of the request.
- *
- * @return The priority of the request
- */
- public Priority getPriority() {
- return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
- }
-
- /**
- * Returns the persistence of the request.
- *
- * @return The persistence of the request, or {@link Persistence#unknown} if
- * the persistence could not be parsed
- */
- public Persistence getPersistence() {
- try {
- return Persistence.valueOf(getField("Persistence"));
- } catch (IllegalArgumentException iae1) {
- return Persistence.unknown;
- }
- }
-
- /**
- * Returns whether this request is on the global queue or on the
- * client-local queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> if the request is on the client-local queue
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
- /**
- * Returns the maximum number of retries for a failed block.
- *
- * @return The maximum number of retries for a failed block, <code>-1</code>
- * for endless retries, <code>-2</code> if the number could not be
- * parsed
- */
- public int getMaxRetries() {
- return FcpUtils.safeParseInt(getField("MaxRetries"), -2);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PersistentPut.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “PersistentPut” message notifies a client about a persistent
- * {@link ClientPut} request.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PersistentPut extends BaseMessage {
-
- /**
- * Creates a new “PersistentPut” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- PersistentPut(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the client token of the request.
- *
- * @return The client token of the request
- */
- public String getClientToken() {
- return getField("ClientToken");
- }
-
- /**
- * Returns the data length of the request.
- *
- * @return The data length of the request, or <code>-1</code> if the length
- * could not be parsed
- */
- public long getDataLength() {
- return FcpUtils.safeParseLong(getField("DataLength"));
- }
-
- /**
- * Returns whether the request is on the global queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> otherwise
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the maximum number of retries for failed blocks. When
- * <code>-1</code> is returned each block is tried forever.
- *
- * @return The maximum number of retries for failed blocks, or
- * <code>-1</code> for unlimited retries, or <code>-2</code> if the
- * number of retries could not be parsed
- */
- public int getMaxRetries() {
- return FcpUtils.safeParseInt(getField("MaxRetries"));
- }
-
- /**
- * Returns the content type of the data.
- *
- * @return The content type
- */
- public String getMetadataContentType() {
- return getField("Metadata.ContentType");
- }
-
- /**
- * Returns the persistence of the request.
- *
- * @return The persistence of the request
- */
- public Persistence getPersistence() {
- return Persistence.valueOf(getField("Persistence"));
- }
-
- /**
- * Returns the priority of the request.
- *
- * @return The priority of the request, or {@link Priority#unknown} if the
- * priority could not be parsed
- */
- public Priority getPriority() {
- return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
- }
-
- /**
- * Returns whether this request has started.
- *
- * @return <code>true</code> if the request has started, <code>false</code>
- * otherwise
- */
- public boolean isStarted() {
- return Boolean.valueOf(getField("Started"));
- }
-
- /**
- * Returns the target filename of the request.
- *
- * @return The target filename of the request
- */
- public String getTargetFilename() {
- return getField("TargetFilename");
- }
-
- /**
- * Returns the upload source of the request.
- *
- * @return The upload source of the request
- */
- public UploadFrom getUploadFrom() {
- return UploadFrom.valueOf(getField("UploadFrom"));
- }
-
- /**
- * Returns the target URI of the request.
- *
- * @return The target URI of the request
- */
- public String getURI() {
- return getField("URI");
- }
-
- /**
- * Returns the verbosity of the request.
- *
- * @return The verbosity of the request
- */
- public Verbosity getVerbosity() {
- return Verbosity.valueOf(getField("Verbosity"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PersistentPutDir.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “PersistentPutDir” is the response to a {@link ClientPutDiskDir} message.
- * It is also sent as a possible response to a {@link ListPersistentRequests}
- * message.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PersistentPutDir extends BaseMessage {
-
- /**
- * Creates a new “PersistentPutDir” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- PersistentPutDir(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the URI of the request.
- *
- * @return The URI of the request
- */
- public String getURI() {
- return getField("URI");
- }
-
- /**
- * Returns the verbosity of the request.
- *
- * @return The verbosity of the request
- */
- public Verbosity getVerbosity() {
- return Verbosity.valueOf(getField("Verbosity"));
- }
-
- /**
- * Returns the priority of the request.
- *
- * @return The priority of the request
- */
- public Priority getPriority() {
- return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
- }
-
- /**
- * Returns whether the request is on the global queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on the client-local queue
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
- /**
- * Returns the maximum number of retries for failed blocks.
- *
- * @return The maximum number of retries, or <code>-1</code> for endless
- * retries, or <code>-2</code> if the number could not be parsed
- */
- public int getMaxRetries() {
- return FcpUtils.safeParseInt(getField("MaxRetries"), -2);
- }
-
- /**
- * Returns the number of files in the request.
- *
- * @return The number of files in the request
- */
- public int getFileCount() {
- int fileCount = -1;
- while (getField("Files." + ++fileCount + ".UploadFrom") != null) {
- /* do nothing. */
- }
- return fileCount;
- }
-
- /**
- * Returns the name of the file at the given index. The index is counted
- * from <code>0</code>.
- *
- * @param fileIndex
- * The index of the file
- * @return The name of the file at the given index
- */
- public String getFileName(int fileIndex) {
- return getField("Files." + fileIndex + ".Name");
- }
-
- /**
- * Returns the length of the file at the given index. The index is counted
- * from <code>0</code>.
- *
- * @param fileIndex
- * The index of the file
- * @return The length of the file at the given index
- */
- public long getFileDataLength(int fileIndex) {
- return FcpUtils.safeParseLong(getField("Files." + fileIndex + ".DataLength"));
- }
-
- /**
- * Returns the upload source of the file at the given index. The index is
- * counted from <code>0</code>.
- *
- * @param fileIndex
- * The index of the file
- * @return The upload source of the file at the given index
- */
- public UploadFrom getFileUploadFrom(int fileIndex) {
- return UploadFrom.valueOf(getField("Files." + fileIndex + ".UploadFrom"));
- }
-
- /**
- * Returns the content type of the file at the given index. The index is
- * counted from <code>0</code>.
- *
- * @param fileIndex
- * The index of the file
- * @return The content type of the file at the given index
- */
- public String getFileMetadataContentType(int fileIndex) {
- return getField("Files." + fileIndex + ".Metadata.ContentType");
- }
-
- /**
- * Returns the filename of the file at the given index. This value is only
- * returned if {@link #getFileUploadFrom(int)} is returning
- * {@link UploadFrom#disk}. The index is counted from <code>0</code>.
- *
- * @param fileIndex
- * The index of the file
- * @return The filename of the file at the given index
- */
- public String getFileFilename(int fileIndex) {
- return getField("Files." + fileIndex + ".Filename");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PersistentRequestModified.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PersistentRequestModified” message is a reply to
- * {@link ModifyPersistentRequest}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PersistentRequestModified extends BaseMessage {
-
- /**
- * Creates a new “PersistentRequestModified” message that wraps the received
- * message.
- *
- * @param receivedMessage
- * The received message
- */
- PersistentRequestModified(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the changed request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns whether the request is on the global queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on a client-local queue
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
- /**
- * Returns the client token, if it was changed.
- *
- * @return The new client token, or <code>null</code> if the client token
- * was not changed
- */
- public String getClientToken() {
- return getField("ClientToken");
- }
-
- /**
- * Returns the priority of the request, if it was changed.
- *
- * @return The new priority of the request, or {@link Priority#unknown} if
- * the priority was not changed
- */
- public Priority getPriority() {
- return Priority.values()[FcpUtils.safeParseInt(getField("PriorityClass"), Priority.unknown.ordinal())];
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PersistentRequestRemoved.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “PersistentRequestRemoved” message signals that a persistent request was
- * removed from either the global or the client-local queue.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PersistentRequestRemoved extends BaseMessage {
-
- /**
- * Creates a new “PersistentRequestRemoved” message that wraps the received
- * message.
- *
- * @param receivedMessage
- * The received message
- */
- PersistentRequestRemoved(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns whether the request was removed from the global queue.
- *
- * @return <code>true</code> if the request was removed from the global
- * queue, <code>false</code> if it was removed from the client-local
- * queue
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PluginInfo.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PluginInfo” message is a reply to the {@link GetPluginInfo} request.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PluginInfo extends BaseMessage {
-
- /**
- * Creates a new “PluginInfo” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- PluginInfo(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the name of the plugin.
- *
- * @return The name of the plugin
- */
- public String getPluginName() {
- return getField("PluginName");
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the original URI of the plugin.
- *
- * @return The original URI of the plugin
- */
- public String getOriginalURI() {
- return getField("OriginalUri");
- }
-
- /**
- * Returns whether the plugin is started.
- *
- * @return <code>true</code> if the plugin is started, <code>false</code>
- * otherwise
- */
- public boolean isStarted() {
- return Boolean.valueOf("Started");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - Priority.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The priority classes used by the Freenet node.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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());
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ProtocolError.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “ProtocolError” message signals that something has gone really wrong.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ProtocolError extends BaseMessage {
-
- /**
- * Creates a new “ProtocolError” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- ProtocolError(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns whether the causing message had the “Global” flag set.
- *
- * @return <code>true</code> if the causing message had the “Global” flag
- * set
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
- /**
- * Returns the error code.
- *
- * @return The error code, or <code>-1</code> if the error code could not be
- * parsed
- */
- public int getCode() {
- return FcpUtils.safeParseInt(getField("Code"));
- }
-
- /**
- * Returns the description of the error.
- *
- * @return The description of the error
- */
- public String getCodeDescription() {
- return getField("CodeDescription");
- }
-
- /**
- * Returns some extra description of the error.
- *
- * @return Extra description of the error, or <code>null</code> if there is
- * none
- */
- public String getExtraDescription() {
- return getField("ExtraDescription");
- }
-
- /**
- * Returns whether the connection to the node can stay open.
- *
- * @return <code>true</code> when the connection has to be closed,
- * <code>false</code> otherwise
- */
- public boolean isFatal() {
- return Boolean.valueOf(getField("Fatal"));
- }
-
- /**
- * The identifier of the causing request, if any.
- *
- * @return The identifier of the causing request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - GetFailed.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The “PutFailed” message signals the client that a {@link ClientPut} request
- * has failed. This also means that no further progress messages for that
- * request will be sent.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PutFailed extends BaseMessage {
-
- /**
- * Creates a new “PutFailed” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- PutFailed(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the code of the error.
- *
- * @return The code of the error, or <code>-1</code> if the error code could
- * not be parsed
- */
- public int getCode() {
- return FcpUtils.safeParseInt(getField("Code"));
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns whether the request is on the global queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on the client-local queue
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
- /**
- * Returns the description of the error code.
- *
- * @return The description of the error code
- */
- public String getCodeDescription() {
- return getField("CodeDescription");
- }
-
- /**
- * Returns the extra description of the error.
- *
- * @return The extra description of the error
- */
- public String getExtraDescription() {
- return getField("ExtraDescription");
- }
-
- /**
- * Returns the short description of the error.
- *
- * @return The short description of the error
- */
- public String getShortCodeDescription() {
- return getField("ShortCodeDescription");
- }
-
- /**
- * Returns the expected URI of the request.
- *
- * @return The expected URI
- */
- public String getExpectedURI() {
- return getField("ExpectedURI");
- }
-
- /**
- * Returns whether the request failed fatally. If a request fails fatally it
- * can never complete, even with inifinite retries.
- *
- * @return <code>true</code> if the request failed fatally,
- * <code>false</code> otherwise
- */
- public boolean isFatal() {
- return Boolean.valueOf(getField("Fatal"));
- }
-
- /**
- * Returns a list of complex error codes with the message. Use
- * {@link #getComplexErrorDescription(int)} and
- * {@link #getComplexErrorCount(int)} to get details.
- *
- * @return A list of complex error codes
- */
- public int[] getComplexErrorCodes() {
- Map<String, String> allFields = getFields();
- List<Integer> errorCodeList = new ArrayList<Integer>();
- for (Entry<String, String> field : allFields.entrySet()) {
- String fieldKey = field.getKey();
- if (fieldKey.startsWith("Errors.")) {
- int nextDot = fieldKey.indexOf('.', 7);
- if (nextDot > -1) {
- int errorCode = FcpUtils.safeParseInt(fieldKey.substring(7, nextDot));
- if (errorCode != -1) {
- errorCodeList.add(errorCode);
- }
- }
- }
- }
- int[] errorCodes = new int[errorCodeList.size()];
- int errorIndex = 0;
- for (int errorCode : errorCodeList) {
- errorCodes[errorIndex++] = errorCode;
- }
- return errorCodes;
- }
-
- /**
- * Returns the description of the complex error. You should only hand it
- * error codes you got from {@link #getComplexErrorCodes()}!
- *
- * @param errorCode
- * The error code
- * @return The description of the complex error
- */
- public String getComplexErrorDescription(int errorCode) {
- return getField("Errors." + errorCode + ".Description");
- }
-
- /**
- * Returns the count of the complex error. You should only hand it error
- * codes you got from {@link #getComplexErrorCodes()}!
- *
- * @param errorCode
- * The error code
- * @return The count of the complex error, or <code>-1</code> if the count
- * could not be parsed
- */
- public int getComplexErrorCount(int errorCode) {
- return FcpUtils.safeParseInt(getField("Errors." + errorCode + ".Count"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PutFetchable.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PutFetchable” message informs a client that a {@link ClientPut} request
- * has progressed far enough that the resulting final URI might already be
- * fetchable.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PutFetchable extends BaseMessage {
-
- /**
- * Creates a new “PutFetchable” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- PutFetchable(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns whether the request is on the global queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on the client-local queue
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
- /**
- * Returns the URI of the request.
- *
- * @return The URI of the request
- */
- public String getURI() {
- return getField("URI");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PutSuccessful.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “PutSuccessful” message informs a client about a successfully finished
- * {@link ClientPut} (or similar) request.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PutSuccessful extends BaseMessage {
-
- /**
- * Creates a new “PutSuccessful” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- PutSuccessful(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns whether the request is on the global queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on the client-local queue
- */
- public boolean isGlobal() {
- return Boolean.valueOf(getField("Global"));
- }
-
- /**
- * Returns the final URI of the {@link ClientPut} request.
- *
- * @return The final URI of the request
- */
- public String getURI() {
- return getField("URI");
- }
-
- /**
- * Returns the time the insert started.
- *
- * @return The time the insert started (in milliseconds since Jan 1, 1970
- * UTC), or <code>-1</code> if the time could not be parsed
- */
- public long getStartupTime() {
- return FcpUtils.safeParseLong(getField("StartupTime"));
- }
-
- /**
- * Returns the time the insert completed.
- *
- * @return The time the insert completed (in milliseconds since Jan 1, 1970
- * UTC), or <code>-1</code> if the time could not be parsed
- */
- public long getCompletionTime() {
- return FcpUtils.safeParseLong(getField("CompletionTime"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ReceivedBookmarkFeed.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Implementation of the “ReceivedBookmarkFeed” FCP message. This message
- * notifies an FCP client that an update for a bookmark has been found.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ReceivedBookmarkFeed extends BaseMessage {
-
- /**
- * Creates a new “ReceivedBookmarkFeed” message.
- *
- * @param fcpMessage
- * The FCP message to get the fields from
- */
- public ReceivedBookmarkFeed(FcpMessage fcpMessage) {
- super(fcpMessage);
- }
-
- /**
- * Returns the name of the bookmark.
- *
- * @return The bookmark’s name
- */
- public String getBookmarkName() {
- return getField("Name");
- }
-
- /**
- * Returns the URI of the updated bookmark.
- *
- * @return The bookmark’s URI
- */
- public String getURI() {
- return getField("URI");
- }
-
- /**
- * Returns whether the bookmark has an active link image.
- *
- * @return {@code true} if the bookmark has an active link image, {@code
- * false} otherwise
- */
- public boolean hasActiveLink() {
- return Boolean.parseBoolean(getField("HasAnActiveLink"));
- }
-
- /**
- * Returns the description of the bookmark. Note that the description may be
- * {@code null} and if it is not, it is base64-encoded!
- *
- * @return The bookmark’s description, or {@code null} if the bookmark has
- * no description
- */
- public String getDescription() {
- return getField("Description");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - RemovePeer.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “RemovePeer” command removes a peer.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - RemovePersistentRequest.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “RemovePersistentRequest” message tells the node to remove a persistent
- * request, cancelling it first (resulting in a {@link GetFailed} or
- * {@link PutFailed} message), if necessary.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class RemovePersistentRequest extends FcpMessage {
-
- /**
- * Creates a new “RemovePersistentRequest” message.
- *
- * @param identifier
- * The identifier of the request
- */
- public RemovePersistentRequest(String identifier) {
- super("RemovePersistentRequest");
- setField("Identifier", identifier);
- }
-
- /**
- * Sets whether the request is on the global queue.
- *
- * @param global
- * <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on the client-local queue
- */
- public void setGlobal(boolean global) {
- setField("Global", String.valueOf(global));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - ReturnType.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The different return types for {@link ClientGet} requests.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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;
-
-}
+++ /dev/null
-/*
- * jFCPlib - SSKKeypair.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * An “SSKKeypair” message that is sent as a response to a {@link GenerateSSK}
- * message.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - SendBookmarkFeed.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “SendBookmarkFeed” command sends a bookmark to a peer.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class SendBookmarkFeed extends AbstractSendFeedMessage {
-
- /**
- * Creates a new “SendBookmarkFeed” command.
- *
- * @param identifier
- * The identifier of the request
- * @param nodeIdentifier
- * The identifier of the peer node
- * @param name
- * The name of the bookmark
- * @param uri
- * The URI of the bookmark
- * @param description
- * The description of the bookmark (may be {@code null})
- * @param hasActiveLink
- * {@code true} if the bookmark has an activelink image, {@code
- * false} otherwise
- */
- public SendBookmarkFeed(String identifier, String nodeIdentifier, String name, String uri, String description, boolean hasActiveLink) {
- super("SendBookmarkFeed", identifier, nodeIdentifier);
- setField("Name", name);
- setField("URI", uri);
- setField("Description", description);
- setField("HasActiveLink", String.valueOf(hasActiveLink));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - SendDownloadFeed.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “SendDownloadFeed” command sends information about a download to a peer
- * node.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class SendDownloadFeed extends AbstractSendFeedMessage {
-
- /**
- * Creates a new “SendDownloadFeed” to a peer node.
- *
- * @param identifier
- * The identifier of the request
- * @param nodeIdentifier
- * The identifier of the peer node
- * @param uri
- * The URI of the download to send
- * @param description
- * The description of the download (may be {@code null})
- */
- public SendDownloadFeed(String identifier, String nodeIdentifier, String uri, String description) {
- super("SendDownloadFeed", identifier, nodeIdentifier);
- setField("URI", uri);
- setField("Description", description);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - SendTextFeed.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “SendTextFeed” command sends an arbitrary text to a peer node.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class SendTextFeed extends AbstractSendFeedMessage {
-
- /**
- * Creates a new “SendTextFeed” command.
- *
- * @param identifier
- * The identifier of the request
- * @param nodeIdentifier
- * The identifier of the peer node
- * @param text
- * The text to send
- */
- public SendTextFeed(String identifier, String nodeIdentifier, String text) {
- super("SendTextFeed", identifier, nodeIdentifier);
- setField("Text", text);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - SentFeed.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “SentFeed” message signals that a feed was successfully sent to a peer.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class SentFeed extends BaseMessage {
-
- /**
- * Creates a new “SentFeed” message from the given FCP message.
- *
- * @param fcpMessage
- * The FCP message containing the “SentFeed” message
- */
- public SentFeed(FcpMessage fcpMessage) {
- super(fcpMessage);
- }
-
- /**
- * Returns the identifier of the sent feed. The identifier of this message
- * matches the identifier that was given when a {@link SendBookmarkFeed},
- * {@link SendDownloadFeed}, or {@link SendTextFeed} command was created.
- *
- * @return The send feed’s identifier
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the node status of the peer. The node status is definied in
- * {@code freenet.node.PeerManager}.
- * <p>
- * <ol start="1">
- * <li>Connected</li>
- * <li>Backed off</li>
- * <li>Version too new</li>
- * <li>Version too old</li>
- * <li>Disconnected</li>
- * <li>Never connected</li>
- * <li>Disabled</li>
- * <li>Bursting</li>
- * <li>Listening</li>
- * <li>Listening only</li>
- * <li>Clock problem</li>
- * <li>Connection error</li>
- * <li>Disconnecting</li>
- * <li>Routing disabled</li>
- * </ol>
- *
- * @return The node’s status
- */
- public int getNodeStatus() {
- return FcpUtils.safeParseInt(getField("NodeStatus"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - Shutdown.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Command that shuts down the node.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class Shutdown extends FcpMessage {
-
- /**
- * Creates a new “Shutdown” message.
- */
- public Shutdown() {
- super("Shutdown");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - SimpleProgress.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “SimpleProgress” message tells the client about the progress of a
- * {@link ClientGet} or {@link ClientPut} operation.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class SimpleProgress extends BaseMessage {
-
- /**
- * Creates a new “SimpleProgress” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- SimpleProgress(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the total number of blocks. This number may increase as long as
- * {@link #isFinalizedTotal()} returns <code>false</code>.
- *
- * @return The total number of blocks
- */
- public int getTotal() {
- return FcpUtils.safeParseInt(getField("Total"));
- }
-
- /**
- * Returns the number of blocks that are required to completet the request.
- * This number might actually be lower than {@link #getTotal} because of
- * redundancy information. This number may also increase as long as
- * {@link #isFinalizedTotal()} returns <code>false</code>.
- *
- * @return The number of required blocks
- */
- public int getRequired() {
- return FcpUtils.safeParseInt(getField("Required"));
- }
-
- /**
- * Returns the number of blocks that have failed and run out of retries.
- *
- * @return The number of failed blocks
- */
- public int getFailed() {
- return FcpUtils.safeParseInt(getField("Failed"));
- }
-
- /**
- * Returns the number of fatally failed blocks. A block that failed fatally
- * can never be completed, even with infinite retries.
- *
- * @return The number of fatally failed blocks
- */
- public int getFatallyFailed() {
- return FcpUtils.safeParseInt(getField("FatallyFailed"));
- }
-
- /**
- * Returns the number of blocks that have been successfully processed.
- *
- * @return The number of succeeded blocks
- */
- public int getSucceeded() {
- return FcpUtils.safeParseInt(getField("Succeeded"));
- }
-
- /**
- * Returns whether the total number of blocks (see {@link #getTotal()} has
- * been finalized. Once the total number of blocks has been finalized for a
- * request it will not change any more, and this method of every further
- * SimpleProgress message will always return <code>true</code>.
- *
- * @return <code>true</code> if the number of total blocks has been
- * finalized, <code>false</code> otherwise
- */
- public boolean isFinalizedTotal() {
- return Boolean.valueOf(getField("FinalizedTotal"));
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - StartedCompression.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “StartedCompression” message signals the client the compressing for a
- * request has started.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class StartedCompression extends BaseMessage {
-
- /**
- * Creates a new “StartedCompression” message that wraps the received
- * message.
- *
- * @param receivedMessage
- * The received message
- */
- StartedCompression(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the number of the codec that is used for compression.
- *
- * @return The codec used for the compression, or <code>-1</code> if the
- * codec could not be parsed
- */
- public int getCodec() {
- return FcpUtils.safeParseInt(getField("Codec"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - SubscribeFeeds.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “SubscribeFeeds” command tells the node that the client is interested in
- * receiving the feeds sent by peer nodes.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class SubscribeFeeds extends FcpMessage {
-
- /**
- * Creates a new “SubscribeFeeds” command.
- *
- * @param identifier
- * The identifier of the request
- */
- public SubscribeFeeds(String identifier) {
- super("SubscribeFeeds");
- setField("Identifier", identifier);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - SubscribeUSK.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * With a “SubscribeUSK” a client requests to be notified if the edition number
- * of a USK changes.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class SubscribeUSK extends FcpMessage {
-
- /**
- * Creates a new “SubscribeUSK” message.
- *
- * @param uri
- * The URI to watch for changes
- * @param identifier
- * The identifier of the request
- */
- public SubscribeUSK(String uri, String identifier) {
- super("SubscribeUSK");
- setField("URI", uri);
- setField("Identifier", identifier);
- }
-
- /**
- * Sets whether updates for the USK are actively searched.
- *
- * @param active
- * <code>true</code> to actively search for newer editions,
- * <code>false</code> to only watch for newer editions that are
- * found from other requests
- */
- public void setActive(boolean active) {
- setField("DontPoll", String.valueOf(!active));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - SubscribedUSKUpdate.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “SubscribedUSKUpdate” message is sent each time a new edition of a USK that
- * was previously subscribed to with {@link SubscribeUSK} was found. Note that
- * if the new edition that was found is several editions ahead of the currently
- * last known edition, you will received a SubscribedUSKUpdate for each edition
- * inbetween as welL!
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - TestDDAComplete.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “TestDDAComplete” message signals that the node has finished checking
- * your read and write access to a certain directory.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class TestDDAComplete extends BaseMessage {
-
- /**
- * Creates a new “TestDDAComplete” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- TestDDAComplete(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the directory the authorization is given for.
- *
- * @return The directory that was tested for read and/or write access
- */
- public String getDirectory() {
- return getField("Directory");
- }
-
- /**
- * Returns whether read access to the directory is allowed.
- *
- * @return <code>true</code> if the client is allowed to read from that
- * directory, <code>false</code> otherwise
- */
- public boolean isReadDirectoryAllowed() {
- return Boolean.valueOf(getField("ReadDirectoryAllowed"));
- }
-
- /**
- * Returns whether write access to the directory is allowed.
- *
- * @return <code>true</code> if the client is allowed to write into that
- * directory, <code>false</code> otherwise
- */
- public boolean isWriteDirectoryAllowed() {
- return Boolean.valueOf(getField("WriteDirectoryAllowed"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - TestDDAReply.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “TestDDAReply” is sent as a response to {@link TestDDARequest}. If you
- * specified that you wanted to read files from that directory
- * {@link #getReadFilename()} will give you a filename. Similarly, if you
- * specified that you want to write in the directory {@link #getWriteFilename()}
- * will give you a filename to write {@link #getContentToWrite()} to.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - TestDDARequest.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “TestDDARequest” initiates a DDA test sequence.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class TestDDARequest extends FcpMessage {
-
- /**
- * Creates a new “TestDDARequest” command that initiates a DDA test.
- *
- * @param directory
- * The directory you want to access files in
- * @param wantReadDirectory
- * <code>true</code> if you want to read files from the directory
- * @param wantWriteDirectory
- * <code>true</code> if you want to write files to the directory
- */
- public TestDDARequest(String directory, boolean wantReadDirectory, boolean wantWriteDirectory) {
- super("TestDDARequest");
- setField("Directory", directory);
- setField("WantReadDirectory", String.valueOf(wantReadDirectory));
- setField("WantWriteDirectory", String.valueOf(wantWriteDirectory));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - TestDDAResponse.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * A “TestDDAResponse” is sent to let the node know that either created a file
- * with the content from {@link TestDDAReply#getContentToWrite()} or that you
- * read the content of the file given by {@link TestDDAReply#getReadFilename()}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class TestDDAResponse extends FcpMessage {
-
- /**
- * Creates a new “TestDDAResponse” message that signals that you created the
- * file given by {@link TestDDAReply#getWriteFilename()} and wrote the
- * contents given by {@link TestDDAReply#getContentToWrite()} to it.
- *
- * @param directory
- * The directory from the {@link TestDDARequest} command
- */
- public TestDDAResponse(String directory) {
- this(directory, null);
- }
-
- /**
- * Creates a new “TestDDAResponse” message that signals that you created the
- * file given by {@link TestDDAReply#getWriteFilename()} with the contents
- * given by {@link TestDDAReply#getContentToWrite()} to it (when you
- * specified that you want to write to the directory) and/or that you read
- * the file given by {@link TestDDAReply#getReadFilename()} (when you
- * specified you wanted to read the directory).
- *
- * @param directory
- * The directory from the {@link TestDDARequest} command
- * @param readContent
- * The read content, or <code>null</code> if you did not request
- * read access
- */
- public TestDDAResponse(String directory, String readContent) {
- super("TestDDAResponse");
- if (readContent != null) {
- setField("ReadContent", readContent);
- }
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - URIGenerated.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “URIGenerated” message signals the client that an URI was generated for a
- * {@link ClientPut} (or {@link ClientPutDiskDir} or {@link ClientPutComplexDir}
- * ) request.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class URIGenerated extends BaseMessage {
-
- /**
- * Creates a new “URIGenerated” message that wraps the received message.
- *
- * @param receivedMessage
- * The received message
- */
- URIGenerated(FcpMessage receivedMessage) {
- super(receivedMessage);
- }
-
- /**
- * Returns the identifier of the request that generated an URI.
- *
- * @return The identifier of the request
- */
- public String getIdentifier() {
- return getField("Identifier");
- }
-
- /**
- * Returns the URI that was generated by the request.
- *
- * @return The URI that was generated by the request
- */
- public String getURI() {
- return getField("URI");
- }
-
- /**
- * Returns whether the request that generated the URI is on the global queue
- * or on the client-local queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> if it is on the client-local queue
- */
- public boolean isGlobal() {
- return Boolean.parseBoolean(getField("Global"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - UnknownNodeIdentifier.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “UnknownNodeIdentifier” message signals the client that the node
- * identifier given in a command like {@link ListPeer} is unknown.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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");
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - UnknownPeerNoteType.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The ”UnknownPeerNoteType” message signals the client that the type of peer
- * note used in a previous {@link ModifyPeerNote} is unknown.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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"));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - UploadFrom.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Enumeration for the different values for the “UploadFrom” field in
- * {@link ClientPut} and {@link ClientGet} requests.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-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;
-
-}
+++ /dev/null
-/*
- * jFCPlib - Verbosity.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * Convenicence class for verbosity handling. This might come in handy with the
- * {@link ClientPut} and {@link ClientGet} requests. The verbosity is a bit-mask
- * that can be composed of several bits. {@link #PROGRESS} and
- * {@link #COMPRESSION} are single bits in that mask and can be combined into a
- * new verbosity using {@link #add(Verbosity)}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class Verbosity {
-
- /** Constant for no verbosity at all. */
- public static final Verbosity NONE = new Verbosity(0);
-
- /** Constant for progress message verbosity. */
- public static final Verbosity PROGRESS = new Verbosity(1);
-
- /** Constant for compression message verbosity. */
- public static final Verbosity COMPRESSION = new Verbosity(512);
-
- /** Constant for all events. */
- public static final Verbosity ALL = new Verbosity(-1);
-
- /** The verbosity level. */
- private final int level;
-
- /**
- * Creates a new verbosity with the given level.
- *
- * @param level
- * The verbosity level
- */
- private Verbosity(int level) {
- this.level = level;
- }
-
- /**
- * Adds the given verbosity to this verbosity and returns a verbosity with
- * the new value. The value of this verbosity is not changed.
- *
- * @param verbosity
- * The verbosity to add to this verbosity
- * @return The verbosity with the new level.
- */
- public Verbosity add(Verbosity verbosity) {
- return new Verbosity(level | verbosity.level);
- }
-
- /**
- * Checks whether this Verbosity contains all bits of the given Verbosity.
- *
- * @param verbosity
- * The verbosity to check for in this Verbosity
- * @return <code>true</code> if and only if all set bits in the given
- * Verbosity are also set in this Verbosity
- */
- public boolean contains(Verbosity verbosity) {
- return (level & verbosity.level) == verbosity.level;
- }
-
- /**
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return String.valueOf(level);
- }
-
- /**
- * Parses the given string and creates a Verbosity with the given level.
- *
- * @param s
- * The string to parse
- * @return The parsed verbosity, or {@link #NONE} if the string could not be
- * parsed
- */
- public static Verbosity valueOf(String s) {
- try {
- return new Verbosity(Integer.valueOf(s));
- } catch (NumberFormatException nfe1) {
- return NONE;
- }
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - Version.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.util.StringTokenizer;
-
-/**
- * Container for the “lastGoodVersion” field.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class Version {
-
- /** The name of the node implementation. */
- private final String nodeName;
-
- /** The tree version of the node. */
- private final String treeVersion;
-
- /** The protocol version of the node. */
- private final String protocolVersion;
-
- /** The build number of the node. */
- private final int buildNumber;
-
- /**
- * Creates a new Version from the given string. The string consists of the
- * four required fields node name, tree version, protocol version, and build
- * number, separated by a comma.
- *
- * @param version
- * The version string
- * @throws NullPointerException
- * if <code>version</code> is <code>null</code>
- * @throws IllegalArgumentException
- * if <code>version</code> is not in the right format
- */
- public Version(String version) {
- if (version == null) {
- throw new NullPointerException("version must not be null");
- }
- StringTokenizer versionTokens = new StringTokenizer(version, ",");
- if (versionTokens.countTokens() != 4) {
- throw new IllegalArgumentException("version must consist of four fields");
- }
- this.nodeName = versionTokens.nextToken();
- this.treeVersion = versionTokens.nextToken();
- this.protocolVersion = versionTokens.nextToken();
- try {
- this.buildNumber = Integer.valueOf(versionTokens.nextToken());
- } catch (NumberFormatException nfe1) {
- throw new IllegalArgumentException("last part of version must be numeric", nfe1);
- }
- }
-
- /**
- * Creates a new Version from the given parts.
- *
- * @param nodeName
- * The name of the node implementation
- * @param treeVersion
- * The tree version
- * @param protocolVersion
- * The protocol version
- * @param buildNumber
- * The build number of the node
- */
- public Version(String nodeName, String treeVersion, String protocolVersion, int buildNumber) {
- this.nodeName = nodeName;
- this.treeVersion = treeVersion;
- this.protocolVersion = protocolVersion;
- this.buildNumber = buildNumber;
- }
-
- /**
- * Returns the name of the node implementation.
- *
- * @return The node name
- */
- public String getNodeName() {
- return nodeName;
- }
-
- /**
- * The tree version of the node.
- *
- * @return The tree version of the node
- */
- public String getTreeVersion() {
- return treeVersion;
- }
-
- /**
- * The protocol version of the node
- *
- * @return The protocol version of the node
- */
- public String getProtocolVersion() {
- return protocolVersion;
- }
-
- /**
- * The build number of the node.
- *
- * @return The build number of the node
- */
- public int getBuildNumber() {
- return buildNumber;
- }
-
- /**
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return nodeName + "," + treeVersion + "," + protocolVersion + "," + buildNumber;
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - WatchGlobal.java - Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-/**
- * The “WatchGlobal” messages enables clients to watch the global queue in
- * addition to the client-local queue.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class WatchGlobal extends FcpMessage {
-
- /**
- * Enables or disables watching the global queue.
- *
- * @param enabled
- * <code>true</code> to watch the global queue and the
- * client-local queue, <code>false</code> to watch only the
- * client-local queue
- */
- public WatchGlobal(boolean enabled) {
- this(enabled, Verbosity.ALL);
- }
-
- /**
- * Enables or disables watching the global queue, optionally masking out
- * certain events.
- *
- * @param enabled
- * <code>true</code> to watch the global queue and the
- * client-local queue, <code>false</code> to watch only the
- * client-local queue
- * @param verbosityMask
- * A verbosity mask that determines which events are received
- */
- public WatchGlobal(boolean enabled, Verbosity verbosityMask) {
- super("WatchGlobal");
- setField("Enabled", String.valueOf(enabled));
- setField("VerbosityMask", String.valueOf(verbosityMask));
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpClient.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-import java.util.concurrent.CountDownLatch;
-
-import net.pterodactylus.fcp.AddPeer;
-import net.pterodactylus.fcp.ClientHello;
-import net.pterodactylus.fcp.CloseConnectionDuplicateClientName;
-import net.pterodactylus.fcp.DataFound;
-import net.pterodactylus.fcp.EndListPeerNotes;
-import net.pterodactylus.fcp.EndListPeers;
-import net.pterodactylus.fcp.EndListPersistentRequests;
-import net.pterodactylus.fcp.FCPPluginMessage;
-import net.pterodactylus.fcp.FCPPluginReply;
-import net.pterodactylus.fcp.FcpAdapter;
-import net.pterodactylus.fcp.FcpConnection;
-import net.pterodactylus.fcp.FcpListener;
-import net.pterodactylus.fcp.GenerateSSK;
-import net.pterodactylus.fcp.GetFailed;
-import net.pterodactylus.fcp.GetNode;
-import net.pterodactylus.fcp.ListPeerNotes;
-import net.pterodactylus.fcp.ListPeers;
-import net.pterodactylus.fcp.ListPersistentRequests;
-import net.pterodactylus.fcp.ModifyPeer;
-import net.pterodactylus.fcp.ModifyPeerNote;
-import net.pterodactylus.fcp.NodeData;
-import net.pterodactylus.fcp.NodeHello;
-import net.pterodactylus.fcp.NodeRef;
-import net.pterodactylus.fcp.Peer;
-import net.pterodactylus.fcp.PeerNote;
-import net.pterodactylus.fcp.PeerRemoved;
-import net.pterodactylus.fcp.PersistentGet;
-import net.pterodactylus.fcp.PersistentPut;
-import net.pterodactylus.fcp.ProtocolError;
-import net.pterodactylus.fcp.RemovePeer;
-import net.pterodactylus.fcp.SSKKeypair;
-import net.pterodactylus.fcp.SimpleProgress;
-import net.pterodactylus.fcp.WatchGlobal;
-import net.pterodactylus.util.filter.Filter;
-import net.pterodactylus.util.filter.Filters;
-import net.pterodactylus.util.thread.ObjectWrapper;
-
-/**
- * High-level FCP client that hides the details of the underlying FCP
- * implementation.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpClient {
-
- /** Object used for synchronization. */
- private final Object syncObject = new Object();
-
- /** Listener management. */
- private final FcpClientListenerManager fcpClientListenerManager = new FcpClientListenerManager(this);
-
- /** The name of this client. */
- private final String name;
-
- /** The underlying FCP connection. */
- private final FcpConnection fcpConnection;
-
- /** Whether the client is currently connected. */
- private volatile boolean connected;
-
- /**
- * Creates an FCP client with the given name.
- *
- * @param name
- * The name of the FCP client
- * @throws UnknownHostException
- * if the hostname “localhost” is unknown
- */
- public FcpClient(String name) throws UnknownHostException {
- this(name, "localhost");
- }
-
- /**
- * Creates an FCP client.
- *
- * @param name
- * The name of the FCP client
- * @param hostname
- * The hostname of the Freenet node
- * @throws UnknownHostException
- * if the given hostname can not be resolved
- */
- public FcpClient(String name, String hostname) throws UnknownHostException {
- this(name, hostname, FcpConnection.DEFAULT_PORT);
- }
-
- /**
- * Creates an FCP client.
- *
- * @param name
- * The name of the FCP client
- * @param hostname
- * The hostname of the Freenet node
- * @param port
- * The Freenet node’s FCP port
- * @throws UnknownHostException
- * if the given hostname can not be resolved
- */
- public FcpClient(String name, String hostname, int port) throws UnknownHostException {
- this(name, InetAddress.getByName(hostname), port);
- }
-
- /**
- * Creates an FCP client.
- *
- * @param name
- * The name of the FCP client
- * @param host
- * The host address of the Freenet node
- */
- public FcpClient(String name, InetAddress host) {
- this(name, host, FcpConnection.DEFAULT_PORT);
- }
-
- /**
- * Creates an FCP client.
- *
- * @param name
- * The name of the FCP client
- * @param host
- * The host address of the Freenet node
- * @param port
- * The Freenet node’s FCP port
- */
- public FcpClient(String name, InetAddress host, int port) {
- this.name = name;
- fcpConnection = new FcpConnection(host, port);
- fcpConnection.addFcpListener(new FcpAdapter() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- @SuppressWarnings("synthetic-access")
- public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
- connected = false;
- fcpClientListenerManager.fireFcpClientDisconnected();
- }
- });
- }
-
- //
- // LISTENER MANAGEMENT
- //
-
- /**
- * Adds an FCP listener to the underlying connection.
- *
- * @param fcpListener
- * The FCP listener to add
- */
- public void addFcpListener(FcpListener fcpListener) {
- fcpConnection.addFcpListener(fcpListener);
- }
-
- /**
- * Removes an FCP listener from the underlying connection.
- *
- * @param fcpListener
- * The FCP listener to remove
- */
- public void removeFcpListener(FcpListener fcpListener) {
- fcpConnection.removeFcpListener(fcpListener);
- }
-
- /**
- * Adds an FCP client listener to the list of registered listeners.
- *
- * @param fcpClientListener
- * The FCP client listener to add
- */
- public void addFcpClientListener(FcpClientListener fcpClientListener) {
- fcpClientListenerManager.addListener(fcpClientListener);
- }
-
- /**
- * Removes an FCP client listener from the list of registered listeners.
- *
- * @param fcpClientListener
- * The FCP client listener to remove
- */
- public void removeFcpClientListener(FcpClientListener fcpClientListener) {
- fcpClientListenerManager.removeListener(fcpClientListener);
- }
-
- //
- // ACTIONS
- //
-
- /**
- * Connects the FCP client.
- *
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void connect() throws IOException, FcpException {
- checkConnected(false);
- connected = true;
- new ExtendedFcpAdapter() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- fcpConnection.connect();
- ClientHello clientHello = new ClientHello(name);
- fcpConnection.sendMessage(clientHello);
- WatchGlobal watchGlobal = new WatchGlobal(true);
- fcpConnection.sendMessage(watchGlobal);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedNodeHello(FcpConnection fcpConnection, NodeHello nodeHello) {
- completionLatch.countDown();
- }
- }.execute();
- }
-
- /**
- * Disconnects the FCP client.
- */
- public void disconnect() {
- synchronized (syncObject) {
- fcpConnection.close();
- syncObject.notifyAll();
- }
- }
-
- /**
- * Returns whether this client is currently connected.
- *
- * @return {@code true} if the client is currently connected, {@code false}
- * otherwise
- */
- public boolean isConnected() {
- return connected;
- }
-
- //
- // PEER MANAGEMENT
- //
-
- /**
- * Returns all peers that the node has.
- *
- * @param withMetadata
- * <code>true</code> to include peer metadata
- * @param withVolatile
- * <code>true</code> to include volatile peer data
- * @return A set containing the node’s peers
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Collection<Peer> getPeers(final boolean withMetadata, final boolean withVolatile) throws IOException, FcpException {
- final Set<Peer> peers = Collections.synchronizedSet(new HashSet<Peer>());
- new ExtendedFcpAdapter() {
-
- /** The ID of the “ListPeers” request. */
- @SuppressWarnings("synthetic-access")
- private String identifier = createIdentifier("list-peers");
-
- /**
- * {@inheritDoc}
- */
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- fcpConnection.sendMessage(new ListPeers(identifier, withMetadata, withVolatile));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
- if (peer.getIdentifier().equals(identifier)) {
- peers.add(peer);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedEndListPeers(FcpConnection fcpConnection, EndListPeers endListPeers) {
- if (endListPeers.getIdentifier().equals(identifier)) {
- completionLatch.countDown();
- }
- }
- }.execute();
- return peers;
- }
-
- /**
- * Returns all darknet peers.
- *
- * @param withMetadata
- * <code>true</code> to include peer metadata
- * @param withVolatile
- * <code>true</code> to include volatile peer data
- * @return A set containing the node’s darknet peers
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Collection<Peer> getDarknetPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
- Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
- Collection<Peer> darknetPeers = new HashSet<Peer>();
- for (Peer peer : allPeers) {
- if (!peer.isOpennet() && !peer.isSeed()) {
- darknetPeers.add(peer);
- }
- }
- return darknetPeers;
- }
-
- /**
- * Returns all opennet peers.
- *
- * @param withMetadata
- * <code>true</code> to include peer metadata
- * @param withVolatile
- * <code>true</code> to include volatile peer data
- * @return A set containing the node’s opennet peers
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Collection<Peer> getOpennetPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
- Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
- Collection<Peer> opennetPeers = new HashSet<Peer>();
- for (Peer peer : allPeers) {
- if (peer.isOpennet() && !peer.isSeed()) {
- opennetPeers.add(peer);
- }
- }
- return opennetPeers;
- }
-
- /**
- * Returns all seed peers.
- *
- * @param withMetadata
- * <code>true</code> to include peer metadata
- * @param withVolatile
- * <code>true</code> to include volatile peer data
- * @return A set containing the node’s seed peers
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Collection<Peer> getSeedPeers(boolean withMetadata, boolean withVolatile) throws IOException, FcpException {
- Collection<Peer> allPeers = getPeers(withMetadata, withVolatile);
- Collection<Peer> seedPeers = new HashSet<Peer>();
- for (Peer peer : allPeers) {
- if (peer.isSeed()) {
- seedPeers.add(peer);
- }
- }
- return seedPeers;
- }
-
- /**
- * Adds the given peer to the node.
- *
- * @param peer
- * The peer to add
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void addPeer(Peer peer) throws IOException, FcpException {
- addPeer(peer.getNodeRef());
- }
-
- /**
- * Adds the peer defined by the noderef to the node.
- *
- * @param nodeRef
- * The noderef that defines the new peer
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void addPeer(NodeRef nodeRef) throws IOException, FcpException {
- addPeer(new AddPeer(nodeRef));
- }
-
- /**
- * Adds a peer, reading the noderef from the given URL.
- *
- * @param url
- * The URL to read the noderef from
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void addPeer(URL url) throws IOException, FcpException {
- addPeer(new AddPeer(url));
- }
-
- /**
- * Adds a peer, reading the noderef of the peer from the given file.
- * <strong>Note:</strong> the file to read the noderef from has to reside on
- * the same machine as the node!
- *
- * @param file
- * The name of the file containing the peer’s noderef
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void addPeer(String file) throws IOException, FcpException {
- addPeer(new AddPeer(file));
- }
-
- /**
- * Sends the given {@link AddPeer} message to the node. This method should
- * not be called directly. Use one of {@link #addPeer(Peer)},
- * {@link #addPeer(NodeRef)}, {@link #addPeer(URL)}, or
- * {@link #addPeer(String)} instead.
- *
- * @param addPeer
- * The “AddPeer” message
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- private void addPeer(final AddPeer addPeer) throws IOException, FcpException {
- new ExtendedFcpAdapter() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- fcpConnection.sendMessage(addPeer);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
- completionLatch.countDown();
- }
- }.execute();
- }
-
- /**
- * Modifies the given peer.
- *
- * @param peer
- * The peer to modify
- * @param allowLocalAddresses
- * <code>true</code> to allow local address, <code>false</code>
- * to not allow local address, <code>null</code> to not change
- * the setting
- * @param disabled
- * <code>true</code> to disable the peer, <code>false</code> to
- * enable the peer, <code>null</code> to not change the setting
- * @param listenOnly
- * <code>true</code> to enable “listen only” for the peer,
- * <code>false</code> to disable it, <code>null</code> to not
- * change it
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void modifyPeer(final Peer peer, final Boolean allowLocalAddresses, final Boolean disabled, final Boolean listenOnly) throws IOException, FcpException {
- new ExtendedFcpAdapter() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- fcpConnection.sendMessage(new ModifyPeer(peer.getIdentity(), allowLocalAddresses, disabled, listenOnly));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedPeer(FcpConnection fcpConnection, Peer peer) {
- completionLatch.countDown();
- }
- }.execute();
- }
-
- /**
- * Removes the given peer.
- *
- * @param peer
- * The peer to remove
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void removePeer(final Peer peer) throws IOException, FcpException {
- new ExtendedFcpAdapter() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- fcpConnection.sendMessage(new RemovePeer(peer.getIdentity()));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedPeerRemoved(FcpConnection fcpConnection, PeerRemoved peerRemoved) {
- completionLatch.countDown();
- }
- }.execute();
- }
-
- //
- // PEER NOTES MANAGEMENT
- //
-
- /**
- * Returns the peer note of the given peer.
- *
- * @param peer
- * The peer to get the note for
- * @return The peer’s note
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public PeerNote getPeerNote(final Peer peer) throws IOException, FcpException {
- final ObjectWrapper<PeerNote> objectWrapper = new ObjectWrapper<PeerNote>();
- new ExtendedFcpAdapter() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- fcpConnection.sendMessage(new ListPeerNotes(peer.getIdentity()));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedPeerNote(FcpConnection fcpConnection, PeerNote peerNote) {
- if (peerNote.getNodeIdentifier().equals(peer.getIdentity())) {
- objectWrapper.set(peerNote);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedEndListPeerNotes(FcpConnection fcpConnection, EndListPeerNotes endListPeerNotes) {
- completionLatch.countDown();
- }
- }.execute();
- return objectWrapper.get();
- }
-
- /**
- * Replaces the peer note for the given peer.
- *
- * @param peer
- * The peer
- * @param noteText
- * The new base64-encoded note text
- * @param noteType
- * The type of the note (currently only <code>1</code> is
- * allowed)
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void modifyPeerNote(final Peer peer, final String noteText, final int noteType) throws IOException, FcpException {
- new ExtendedFcpAdapter() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- fcpConnection.sendMessage(new ModifyPeerNote(peer.getIdentity(), noteText, noteType));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedPeer(FcpConnection fcpConnection, Peer receivedPeer) {
- if (receivedPeer.getIdentity().equals(peer.getIdentity())) {
- completionLatch.countDown();
- }
- }
- }.execute();
- }
-
- //
- // KEY GENERATION
- //
-
- /**
- * Generates a new SSK key pair.
- *
- * @return The generated key pair
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public SSKKeypair generateKeyPair() throws IOException, FcpException {
- final ObjectWrapper<SSKKeypair> sskKeypairWrapper = new ObjectWrapper<SSKKeypair>();
- new ExtendedFcpAdapter() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- fcpConnection.sendMessage(new GenerateSSK());
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedSSKKeypair(FcpConnection fcpConnection, SSKKeypair sskKeypair) {
- sskKeypairWrapper.set(sskKeypair);
- completionLatch.countDown();
- }
- }.execute();
- return sskKeypairWrapper.get();
- }
-
- //
- // REQUEST MANAGEMENT
- //
-
- /**
- * Returns all currently visible persistent get requests.
- *
- * @param global
- * <code>true</code> to return get requests from the global
- * queue, <code>false</code> to only show requests from the
- * client-local queue
- * @return All get requests
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Collection<Request> getGetRequests(final boolean global) throws IOException, FcpException {
- return Filters.filteredCollection(getRequests(global), new Filter<Request>() {
-
- /**
- * {@inheritDoc}
- */
- public boolean filterObject(Request request) {
- return request instanceof GetRequest;
- }
- });
- }
-
- /**
- * Returns all currently visible persistent put requests.
- *
- * @param global
- * <code>true</code> to return put requests from the global
- * queue, <code>false</code> to only show requests from the
- * client-local queue
- * @return All put requests
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Collection<Request> getPutRequests(final boolean global) throws IOException, FcpException {
- return Filters.filteredCollection(getRequests(global), new Filter<Request>() {
-
- /**
- * {@inheritDoc}
- */
- public boolean filterObject(Request request) {
- return request instanceof PutRequest;
- }
- });
- }
-
- /**
- * Returns all currently visible persistent requests.
- *
- * @param global
- * <code>true</code> to return requests from the global queue,
- * <code>false</code> to only show requests from the client-local
- * queue
- * @return All requests
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Collection<Request> getRequests(final boolean global) throws IOException, FcpException {
- final Map<String, Request> requests = Collections.synchronizedMap(new HashMap<String, Request>());
- new ExtendedFcpAdapter() {
-
- /**
- * {@inheritDoc}
- */
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- fcpConnection.sendMessage(new ListPersistentRequests());
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) {
- if (!persistentGet.isGlobal() || global) {
- GetRequest getRequest = new GetRequest(persistentGet);
- requests.put(persistentGet.getIdentifier(), getRequest);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see net.pterodactylus.fcp.FcpAdapter#receivedDataFound(net.pterodactylus.fcp.FcpConnection,
- * net.pterodactylus.fcp.DataFound)
- */
- @Override
- public void receivedDataFound(FcpConnection fcpConnection, DataFound dataFound) {
- Request getRequest = requests.get(dataFound.getIdentifier());
- if (getRequest == null) {
- return;
- }
- getRequest.setComplete(true);
- getRequest.setLength(dataFound.getDataLength());
- getRequest.setContentType(dataFound.getMetadataContentType());
- }
-
- /**
- * {@inheritDoc}
- *
- * @see net.pterodactylus.fcp.FcpAdapter#receivedGetFailed(net.pterodactylus.fcp.FcpConnection,
- * net.pterodactylus.fcp.GetFailed)
- */
- @Override
- public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) {
- Request getRequest = requests.get(getFailed.getIdentifier());
- if (getRequest == null) {
- return;
- }
- getRequest.setComplete(true);
- getRequest.setFailed(true);
- getRequest.setFatal(getFailed.isFatal());
- getRequest.setErrorCode(getFailed.getCode());
- }
-
- /**
- * {@inheritDoc}
- *
- * @see net.pterodactylus.fcp.FcpAdapter#receivedPersistentPut(net.pterodactylus.fcp.FcpConnection,
- * net.pterodactylus.fcp.PersistentPut)
- */
- @Override
- public void receivedPersistentPut(FcpConnection fcpConnection, PersistentPut persistentPut) {
- if (!persistentPut.isGlobal() || global) {
- PutRequest putRequest = new PutRequest(persistentPut);
- requests.put(persistentPut.getIdentifier(), putRequest);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see net.pterodactylus.fcp.FcpAdapter#receivedSimpleProgress(net.pterodactylus.fcp.FcpConnection,
- * net.pterodactylus.fcp.SimpleProgress)
- */
- @Override
- public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) {
- Request request = requests.get(simpleProgress.getIdentifier());
- if (request == null) {
- return;
- }
- request.setTotalBlocks(simpleProgress.getTotal());
- request.setRequiredBlocks(simpleProgress.getRequired());
- request.setFailedBlocks(simpleProgress.getFailed());
- request.setFatallyFailedBlocks(simpleProgress.getFatallyFailed());
- request.setSucceededBlocks(simpleProgress.getSucceeded());
- request.setFinalizedTotal(simpleProgress.isFinalizedTotal());
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedEndListPersistentRequests(FcpConnection fcpConnection, EndListPersistentRequests endListPersistentRequests) {
- completionLatch.countDown();
- }
- }.execute();
- return requests.values();
- }
-
- /**
- * Sends a message to a plugin and waits for the response.
- *
- * @param pluginClass
- * The name of the plugin class
- * @param parameters
- * The parameters for the plugin
- * @return The responses from the plugin
- * @throws FcpException
- * if an FCP error occurs
- * @throws IOException
- * if an I/O error occurs
- */
- public Map<String, String> sendPluginMessage(String pluginClass, Map<String, String> parameters) throws IOException, FcpException {
- return sendPluginMessage(pluginClass, parameters, 0, null);
- }
-
- /**
- * Sends a message to a plugin and waits for the response.
- *
- * @param pluginClass
- * The name of the plugin class
- * @param parameters
- * The parameters for the plugin
- * @param dataLength
- * The length of the optional data stream, or {@code 0} if there
- * is no optional data stream
- * @param dataInputStream
- * The input stream for the payload, or {@code null} if there is
- * no payload
- * @return The responses from the plugin
- * @throws FcpException
- * if an FCP error occurs
- * @throws IOException
- * if an I/O error occurs
- */
- public Map<String, String> sendPluginMessage(final String pluginClass, final Map<String, String> parameters, final long dataLength, final InputStream dataInputStream) throws IOException, FcpException {
- final Map<String, String> pluginReplies = Collections.synchronizedMap(new HashMap<String, String>());
- new ExtendedFcpAdapter() {
-
- @SuppressWarnings("synthetic-access")
- private final String identifier = createIdentifier("FCPPluginMessage");
-
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- FCPPluginMessage fcpPluginMessage = new FCPPluginMessage(pluginClass);
- for (Entry<String, String> parameter : parameters.entrySet()) {
- fcpPluginMessage.setParameter(parameter.getKey(), parameter.getValue());
- }
- fcpPluginMessage.setIdentifier(identifier);
- if ((dataLength > 0) && (dataInputStream != null)) {
- fcpPluginMessage.setDataLength(dataLength);
- fcpPluginMessage.setPayloadInputStream(dataInputStream);
- }
- fcpConnection.sendMessage(fcpPluginMessage);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) {
- if (!fcpPluginReply.getIdentifier().equals(identifier)) {
- return;
- }
- pluginReplies.putAll(fcpPluginReply.getReplies());
- completionLatch.countDown();
- }
-
- }.execute();
- return pluginReplies;
- }
-
- //
- // NODE INFORMATION
- //
-
- /**
- * Returns information about the node.
- *
- * @param giveOpennetRef
- * Whether to return the OpenNet reference
- * @param withPrivate
- * Whether to return private node data
- * @param withVolatile
- * Whether to return volatile node data
- * @return Node information
- * @throws FcpException
- * if an FCP error occurs
- * @throws IOException
- * if an I/O error occurs
- */
- public NodeData getNodeInformation(final Boolean giveOpennetRef, final Boolean withPrivate, final Boolean withVolatile) throws IOException, FcpException {
- final ObjectWrapper<NodeData> nodeDataWrapper = new ObjectWrapper<NodeData>();
- new ExtendedFcpAdapter() {
-
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() throws IOException {
- GetNode getNodeMessage = new GetNode(giveOpennetRef, withPrivate, withVolatile);
- fcpConnection.sendMessage(getNodeMessage);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedNodeData(FcpConnection fcpConnection, NodeData nodeData) {
- nodeDataWrapper.set(nodeData);
- completionLatch.countDown();
- }
- }.execute();
- return nodeDataWrapper.get();
- }
-
- //
- // PRIVATE METHODS
- //
-
- /**
- * Creates a unique request identifier.
- *
- * @param basename
- * The basename of the request
- * @return The created request identifier
- */
- private String createIdentifier(String basename) {
- return basename + "-" + System.currentTimeMillis() + "-" + (int) (Math.random() * Integer.MAX_VALUE);
- }
-
- /**
- * Checks whether the connection is in the required state.
- *
- * @param connected
- * The required connection state
- * @throws FcpException
- * if the connection is not in the required state
- */
- private void checkConnected(boolean connected) throws FcpException {
- if (this.connected != connected) {
- throw new FcpException("Client is " + (connected ? "not" : "already") + " connected.");
- }
- }
-
- /**
- * Tells the client that it is now disconnected. This method is called by
- * {@link ExtendedFcpAdapter} only.
- */
- private void setDisconnected() {
- connected = false;
- }
-
- /**
- * Implementation of an {@link FcpListener} that can store an
- * {@link FcpException} and wait for the arrival of a certain command.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- private abstract class ExtendedFcpAdapter extends FcpAdapter {
-
- /** The count down latch used to wait for completion. */
- protected final CountDownLatch completionLatch = new CountDownLatch(1);
-
- /** The FCP exception, if any. */
- protected FcpException fcpException;
-
- /**
- * Creates a new extended FCP adapter.
- */
- public ExtendedFcpAdapter() {
- /* do nothing. */
- }
-
- /**
- * Executes the FCP commands in {@link #run()}, wrapping the execution
- * and catching exceptions.
- *
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- @SuppressWarnings("synthetic-access")
- public void execute() throws IOException, FcpException {
- checkConnected(true);
- fcpConnection.addFcpListener(this);
- try {
- run();
- while (true) {
- try {
- completionLatch.await();
- break;
- } catch (InterruptedException ie1) {
- /* ignore, we’ll loop. */
- }
- }
- } catch (IOException ioe1) {
- setDisconnected();
- throw ioe1;
- } finally {
- fcpConnection.removeFcpListener(this);
- }
- if (fcpException != null) {
- setDisconnected();
- throw fcpException;
- }
- }
-
- /**
- * The FCP commands that actually get executed.
- *
- * @throws IOException
- * if an I/O error occurs
- */
- public abstract void run() throws IOException;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void connectionClosed(FcpConnection fcpConnection, Throwable throwable) {
- fcpException = new FcpException("Connection closed", throwable);
- completionLatch.countDown();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedCloseConnectionDuplicateClientName(FcpConnection fcpConnection, CloseConnectionDuplicateClientName closeConnectionDuplicateClientName) {
- fcpException = new FcpException("Connection closed, duplicate client name");
- completionLatch.countDown();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
- fcpException = new FcpException("Protocol error (" + protocolError.getCode() + ", " + protocolError.getCodeDescription());
- completionLatch.countDown();
- }
-
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpClientListener.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import java.util.EventListener;
-
-/**
- * Listener for {@link FcpClient} events.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public interface FcpClientListener extends EventListener {
-
- /**
- * Notifies a listener that the given FCP client was disconnected.
- *
- * @param fcpClient
- * The FCP client that was disconnected
- */
- public void fcpClientDisconnected(FcpClient fcpClient);
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpClientListenerManager.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.util.event.AbstractListenerManager;
-
-/**
- * Manages {@link FcpClientListener}s and fires events.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpClientListenerManager extends AbstractListenerManager<FcpClient, FcpClientListener> {
-
- /**
- * Creates a new FCP client listener manager.
- *
- * @param fcpClient
- * The source FCP client
- */
- public FcpClientListenerManager(FcpClient fcpClient) {
- super(fcpClient);
- }
-
- /**
- * Notifies all listeners that the FCP client was disconnected.
- *
- * @see FcpClientListener#fcpClientDisconnected(FcpClient)
- */
- public void fireFcpClientDisconnected() {
- for (FcpClientListener fcpClientListener : getListeners()) {
- fcpClientListener.fcpClientDisconnected(getSource());
- }
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - FcpException.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-/**
- * Exception that signals an error in the FCP protocol.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpException extends Exception {
-
- /**
- * Creates a new FCP exception.
- */
- public FcpException() {
- super();
- }
-
- /**
- * Creates a new FCP exception.
- *
- * @param message
- * The message of the exception
- */
- public FcpException(String message) {
- super(message);
- }
-
- /**
- * Creates a new FCP exception.
- *
- * @param cause
- * The cause of the exception
- */
- public FcpException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Creates a new FCP exception.
- *
- * @param message
- * The message of the exception
- * @param cause
- * The cause of the exception
- */
- public FcpException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - GetRequest.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.fcp.PersistentGet;
-
-/**
- * High-level wrapper around {@link PersistentGet}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class GetRequest extends Request {
-
- /**
- * Creates a new get request.
- *
- * @param persistentGet
- * The persistent Get request to wrap
- */
- GetRequest(PersistentGet persistentGet) {
- super(persistentGet.getIdentifier(), persistentGet.getClientToken(), persistentGet.isGlobal());
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - PutRequest.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.fcp.PersistentPut;
-
-/**
- * TODO
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class PutRequest extends Request {
-
- PutRequest(PersistentPut persistentPut) {
- super(persistentPut.getIdentifier(), persistentPut.getClientToken(), persistentPut.isGlobal());
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - Request.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.highlevel;
-
-import net.pterodactylus.fcp.PersistentGet;
-import net.pterodactylus.fcp.PersistentPut;
-
-/**
- * Wrapper class around request responses from the node, such as
- * {@link PersistentGet} or {@link PersistentPut}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public abstract class Request {
-
- /** The identifier of the request. */
- private final String identifier;
-
- /** The client token of the request. */
- private final String clientToken;
-
- /** Whether the request is on the global queue. */
- private final boolean global;
-
- /** Whether the get request is complete. */
- private boolean complete;
-
- /** Whether the get request has failed. */
- private boolean failed;
-
- /** The data length. */
- private long length;
-
- /** The mime type. */
- private String contentType;
-
- /** The error code in case of failure. */
- private int errorCode;
-
- /** Whether the failure is fatal. */
- private boolean fatal;
-
- /** The total number of blocks. */
- private int totalBlocks;
-
- /** The required number of blocks. */
- private int requiredBlocks;
-
- /** The successfully processed number of blocks. */
- private int succeededBlocks;
-
- /** The number of failed blocks. */
- private int failedBlocks;
-
- /** The number of fatally failed blocks. */
- private int fatallyFailedBlocks;
-
- /** Whether the total number of blocks is finalized. */
- private boolean finalizedTotal;
-
- /**
- * Creates a new request with the given identifier and client token.
- *
- * @param identifier
- * The identifier of the request
- * @param clientToken
- * The client token of the request
- * @param global
- * <code>true</code> if the request is on the global queue,
- * <code>false</code> otherwise
- */
- protected Request(String identifier, String clientToken, boolean global) {
- this.identifier = identifier;
- this.clientToken = clientToken;
- this.global = global;
- }
-
- /**
- * Returns the identifier of the request.
- *
- * @return The request’s identifier
- */
- public String getIdentifier() {
- return identifier;
- }
-
- /**
- * Returns the client token of the request.
- *
- * @return The request’s client token
- */
- public String getClientToken() {
- return clientToken;
- }
-
- /**
- * Returns whether this request is on the global queue.
- *
- * @return <code>true</code> if the request is on the global queue,
- * <code>false</code> otherwise
- */
- public boolean isGlobal() {
- return global;
- }
-
- /**
- * Returns whether this request is complete.
- *
- * @return <code>true</code> if this request is complete, false otherwise
- */
- public boolean isComplete() {
- return complete;
- }
-
- /**
- * Sets whether this request is complete.
- *
- * @param complete
- * <code>true</code> if this request is complete, false otherwise
- */
- void setComplete(boolean complete) {
- this.complete = complete;
- }
-
- /**
- * Returns whether this request has failed. This method should only be
- * called if {@link #isComplete()} returns <code>true</code>.
- *
- * @return <code>true</code> if this request failed, <code>false</code>
- * otherwise
- */
- public boolean hasFailed() {
- return failed;
- }
-
- /**
- * Sets whether this request has failed.
- *
- * @param failed
- * <code>true</code> if this request failed, <code>false</code>
- * otherwise
- */
- void setFailed(boolean failed) {
- this.failed = failed;
- }
-
- /**
- * Returns the length of the data.
- *
- * @return The length of the data
- */
- public long getLength() {
- return length;
- }
-
- /**
- * Sets the length of the data.
- *
- * @param length
- * The length of the data
- */
- void setLength(long length) {
- this.length = length;
- }
-
- /**
- * Returns the content type of the data.
- *
- * @return The content type of the data
- */
- public String getContentType() {
- return contentType;
- }
-
- /**
- * Sets the content type of the data.
- *
- * @param contentType
- * The content type of the data
- */
- void setContentType(String contentType) {
- this.contentType = contentType;
- }
-
- /**
- * Returns the error code. This method should only be called if
- * {@link #hasFailed()} returns <code>true</code>.
- *
- * @return The error code
- */
- public int getErrorCode() {
- return errorCode;
- }
-
- /**
- * Sets the error code.
- *
- * @param errorCode
- * The error code
- */
- void setErrorCode(int errorCode) {
- this.errorCode = errorCode;
- }
-
- /**
- * Returns whether this request has fatally failed, i.e. repitition will not
- * cause the request to succeed.
- *
- * @return <code>true</code> if this request can not be made succeed by
- * repeating, <code>false</code> otherwise
- */
- public boolean isFatal() {
- return fatal;
- }
-
- /**
- * Sets whether this request has fatally failed.
- *
- * @param fatal
- * <code>true</code> if this request failed fatally,
- * <code>false</code> otherwise
- */
- void setFatal(boolean fatal) {
- this.fatal = fatal;
- }
-
- /**
- * Returns the total number of blocks of this request.
- *
- * @return This request’s total number of blocks
- */
- public int getTotalBlocks() {
- return totalBlocks;
- }
-
- /**
- * Sets the total number of blocks of this request.
- *
- * @param totalBlocks
- * This request’s total number of blocks
- */
- public void setTotalBlocks(int totalBlocks) {
- this.totalBlocks = totalBlocks;
- }
-
- /**
- * TODO
- *
- * @return the requiredBlocks
- */
- public int getRequiredBlocks() {
- return requiredBlocks;
- }
-
- /**
- * TODO
- *
- * @param requiredBlocks
- * the requiredBlocks to set
- */
- public void setRequiredBlocks(int requiredBlocks) {
- this.requiredBlocks = requiredBlocks;
- }
-
- /**
- * TODO
- *
- * @return the succeededBlocks
- */
- public int getSucceededBlocks() {
- return succeededBlocks;
- }
-
- /**
- * TODO
- *
- * @param succeededBlocks
- * the succeededBlocks to set
- */
- public void setSucceededBlocks(int succeededBlocks) {
- this.succeededBlocks = succeededBlocks;
- }
-
- /**
- * TODO
- *
- * @return the failedBlocks
- */
- public int getFailedBlocks() {
- return failedBlocks;
- }
-
- /**
- * TODO
- *
- * @param failedBlocks
- * the failedBlocks to set
- */
- public void setFailedBlocks(int failedBlocks) {
- this.failedBlocks = failedBlocks;
- }
-
- /**
- * TODO
- *
- * @return the fatallyFailedBlocks
- */
- public int getFatallyFailedBlocks() {
- return fatallyFailedBlocks;
- }
-
- /**
- * TODO
- *
- * @param fatallyFailedBlocks
- * the fatallyFailedBlocks to set
- */
- public void setFatallyFailedBlocks(int fatallyFailedBlocks) {
- this.fatallyFailedBlocks = fatallyFailedBlocks;
- }
-
- public boolean isFinalizedTotal() {
- return finalizedTotal;
- }
-
- void setFinalizedTotal(boolean finalizedTotal) {
- this.finalizedTotal = finalizedTotal;
- }
-
-}
+++ /dev/null
-/**
- * Package that holds all the message types that are used in the communication
- * with a Freenet Node.
- *
- * <h2>Usage</h2>
- *
- * This library was designed to implement the full range of the Freenet Client
- * Protocol, Version 2.0. At the moment the library provides a rather low-level
- * approach, wrapping each FCP message into its own object but some kind of
- * high-level client that does not require any interfaces to be implemented
- * will probably provided as well.
- *
- * First, create a connection to the node:
- *
- * <pre>
- * FcpConnection fcpConnection = new FcpConnection();
- * </pre>
- *
- * Now implement the {@link net.pterodactylus.fcp.FcpListener} interface
- * and handle all incoming events.
- *
- * <pre>
- * public class MyClass implements FcpListener {
- *
- * public void receivedProtocolError(FcpConnection fcpConnection, ProtocolError protocolError) {
- * …
- * }
- *
- * // implement all further methods here
- *
- * }
- * </pre>
- */
-
-package net.pterodactylus.fcp;
-
+++ /dev/null
-/*
- * jFCPlib - WebOfTrustPlugin.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp.plugin;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import net.pterodactylus.fcp.highlevel.FcpClient;
-import net.pterodactylus.fcp.highlevel.FcpException;
-
-/**
- * Simplifies handling of the web-of-trust plugin.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class WebOfTrustPlugin {
-
- /** The FCP client to use. */
- private final FcpClient fcpClient;
-
- /**
- * Creates a new web-of-trust plugin wrapper around the given FCP client.
- *
- * @param fcpClient
- * The FCP client to use for communication with the web-of-trust
- * plugin
- */
- public WebOfTrustPlugin(FcpClient fcpClient) {
- this.fcpClient = fcpClient;
- }
-
- /**
- * Creates a new identity.
- *
- * @param nickname
- * The nickname of the new identity
- * @param context
- * The context for the new identity
- * @param publishTrustList
- * {@code true} if the new identity should publish its trust list
- * @return The new identity
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList) throws IOException, FcpException {
- return createIdentity(nickname, context, publishTrustList, null, null);
- }
-
- /**
- * Creates a new identity from the given request and insert URI.
- *
- * @param nickname
- * The nickname of the new identity
- * @param context
- * The context for the new identity
- * @param publishTrustList
- * {@code true} if the new identity should publish its trust list
- * @param requestUri
- * The request URI of the identity
- * @param insertUri
- * The insert URI of the identity
- * @return The new identity
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public OwnIdentity createIdentity(String nickname, String context, boolean publishTrustList, String requestUri, String insertUri) throws IOException, FcpException {
- Map<String, String> parameters = new HashMap<String, String>();
- parameters.put("Message", "CreateIdentity");
- parameters.put("Nickname", nickname);
- parameters.put("Context", context);
- parameters.put("PublishTrustList", String.valueOf(publishTrustList));
- if ((requestUri != null) && (insertUri != null)) {
- parameters.put("RequestURI", requestUri);
- parameters.put("InsertURI", insertUri);
- }
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", parameters);
- if (!replies.get("Message").equals("IdentityCreated")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “IdentityCreated” message!");
- }
- String identifier = replies.get("ID");
- String newRequestUri = replies.get("RequestURI");
- String newInsertUri = replies.get("InsertURI");
- return new OwnIdentity(identifier, nickname, newRequestUri, newInsertUri);
- }
-
- /**
- * Returns all own identities of the web-of-trust plugins. Almost all other
- * commands require an {@link OwnIdentity} to return meaningful values.
- *
- * @return All own identities of the web-of-trust plugin
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Set<OwnIdentity> getOwnIdentites() throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetOwnIdentities"));
- if (!replies.get("Message").equals("OwnIdentities")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “OwnIdentities” message!");
- }
- Set<OwnIdentity> ownIdentities = new HashSet<OwnIdentity>();
- for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
- String identity = replies.get("Identity" + identityIndex);
- String nickname = replies.get("Nickname" + identityIndex);
- String requestUri = replies.get("RequestURI" + identityIndex);
- String insertUri = replies.get("InsertURI" + identityIndex);
- ownIdentities.add(new OwnIdentity(identity, nickname, requestUri, insertUri));
- }
- return ownIdentities;
- }
-
- /**
- * Returns the trust given to the identity with the given identifier by the
- * given own identity.
- *
- * @param ownIdentity
- * The own identity that is used to calculate trust values
- * @param identifier
- * The identifier of the identity whose trust to get
- * @return The request identity trust
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public CalculatedTrust getIdentityTrust(OwnIdentity ownIdentity, String identifier) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentity", "TreeOwner", ownIdentity.getIdentifier(), "Identity", identifier));
- if (!replies.get("Message").equals("Identity")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “Identity” message!");
- }
- Byte trust = null;
- try {
- trust = Byte.valueOf(replies.get("Trust"));
- } catch (NumberFormatException nfe1) {
- /* ignore. */
- }
- Integer score = null;
- try {
- score = Integer.valueOf(replies.get("Score"));
- } catch (NumberFormatException nfe1) {
- /* ignore. */
- }
- Integer rank = null;
- try {
- rank = Integer.valueOf(replies.get("Rank"));
- } catch (NumberFormatException nfe1) {
- /* ignore. */
- }
- return new CalculatedTrust(trust, score, rank);
- }
-
- /**
- * Adds a new identity by its request URI.
- *
- * @param requestUri
- * The request URI of the identity to add
- * @return The added identity
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Identity addIdentity(String requestUri) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddIdentity", "RequestURI", requestUri));
- if (!replies.get("Message").equals("IdentityAdded")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “IdentityAdded” message!");
- }
- String identifier = replies.get("ID");
- String nickname = replies.get("Nickname");
- return new Identity(identifier, nickname, requestUri);
- }
-
- /**
- * Returns identities by the given score.
- *
- * @param ownIdentity
- * The own identity
- * @param context
- * The context to get the identities for
- * @param positive
- * {@code null} to return neutrally trusted identities, {@code
- * true} to return positively trusted identities, {@code false}
- * for negatively trusted identities
- * @return The trusted identites
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Set<Identity> getIdentitesByScore(OwnIdentity ownIdentity, String context, Boolean positive) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetIdentitiesByScore", "TreeOwner", ownIdentity.getIdentifier(), "Context", context, "Selection", ((positive == null) ? "0" : (positive ? "+" : "-"))));
- if (!replies.get("Message").equals("Identities")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
- }
- Set<Identity> identities = new HashSet<Identity>();
- for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
- String identifier = replies.get("Identity" + identityIndex);
- String nickname = replies.get("Nickname" + identityIndex);
- String requestUri = replies.get("RequestURI" + identityIndex);
- identities.add(new Identity(identifier, nickname, requestUri));
- }
- return identities;
- }
-
- /**
- * Returns the identities that trust the given identity.
- *
- * @param identity
- * The identity to get the trusters for
- * @param context
- * The context to get the trusters for
- * @return The identities and their trust values
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Map<Identity, IdentityTrust> getTrusters(Identity identity, String context) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrusters", "Identity", identity.getIdentifier(), "Context", context));
- if (!replies.get("Message").equals("Identities")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
- }
- Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
- for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
- String identifier = replies.get("Identity" + identityIndex);
- String nickname = replies.get("Nickname" + identityIndex);
- String requestUri = replies.get("RequestURI" + identityIndex);
- byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
- String comment = replies.get("Comment" + identityIndex);
- identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
- }
- return identityTrusts;
- }
-
- /**
- * Returns the identities that given identity trusts.
- *
- * @param identity
- * The identity to get the trustees for
- * @param context
- * The context to get the trustees for
- * @return The identities and their trust values
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public Map<Identity, IdentityTrust> getTrustees(Identity identity, String context) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetTrustees", "Identity", identity.getIdentifier(), "Context", context));
- if (!replies.get("Message").equals("Identities")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “Identities” message!");
- }
- Map<Identity, IdentityTrust> identityTrusts = new HashMap<Identity, IdentityTrust>();
- for (int identityIndex = 1; replies.containsKey("Identity" + identityIndex); identityIndex++) {
- String identifier = replies.get("Identity" + identityIndex);
- String nickname = replies.get("Nickname" + identityIndex);
- String requestUri = replies.get("RequestURI" + identityIndex);
- byte trust = Byte.parseByte(replies.get("Value" + identityIndex));
- String comment = replies.get("Comment" + identityIndex);
- identityTrusts.put(new Identity(identifier, nickname, requestUri), new IdentityTrust(trust, comment));
- }
- return identityTrusts;
- }
-
- /**
- * Sets the trust given to the given identify by the given own identity.
- *
- * @param ownIdentity
- * The identity that gives the trust
- * @param identity
- * The identity that receives the trust
- * @param trust
- * The trust value (ranging from {@code -100} to {@code 100}
- * @param comment
- * The comment for setting the trust
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void setTrust(OwnIdentity ownIdentity, Identity identity, byte trust, String comment) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetTrust", "Truster", ownIdentity.getIdentifier(), "Trustee", identity.getIdentifier(), "Value", String.valueOf(trust), "Comment", comment));
- if (!replies.get("Message").equals("TrustSet")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “TrustSet” message!");
- }
- }
-
- /**
- * Adds the given context to the given identity.
- *
- * @param ownIdentity
- * The identity to add the context to
- * @param context
- * The context to add
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void addContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "AddContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
- if (!replies.get("Message").equals("ContextAdded")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “ContextAdded” message!");
- }
- }
-
- /**
- * Removes the given context from the given identity.
- *
- * @param ownIdentity
- * The identity to remove the context from
- * @param context
- * The context to remove
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void removeContext(OwnIdentity ownIdentity, String context) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveContext", "Identity", ownIdentity.getIdentifier(), "Context", context));
- if (!replies.get("Message").equals("ContextRemoved")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “ContextRemoved” message!");
- }
- }
-
- /**
- * Sets the given property for the given identity.
- *
- * @param ownIdentity
- * The identity to set a property for
- * @param property
- * The name of the property to set
- * @param value
- * The value of the property to set
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void setProperty(OwnIdentity ownIdentity, String property, String value) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "SetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property, "Value", value));
- if (!replies.get("Message").equals("PropertyAdded")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “PropertyAdded” message!");
- }
- }
-
- /**
- * Returns the value of the given property for the given identity.
- *
- * @param ownIdentity
- * The identity to get a property for
- * @param property
- * The name of the property to get
- * @return The value of the property
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public String getProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "GetProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
- if (!replies.get("Message").equals("PropertyValue")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “PropertyValue” message!");
- }
- return replies.get("Property");
- }
-
- /**
- * Removes the given property from the given identity.
- *
- * @param ownIdentity
- * The identity to remove a property from
- * @param property
- * The name of the property to remove
- * @throws IOException
- * if an I/O error occurs
- * @throws FcpException
- * if an FCP error occurs
- */
- public void removeProperty(OwnIdentity ownIdentity, String property) throws IOException, FcpException {
- Map<String, String> replies = fcpClient.sendPluginMessage("plugins.WoT.WoT", createParameters("Message", "RemoveProperty", "Identity", ownIdentity.getIdentifier(), "Property", property));
- if (!replies.get("Message").equals("PropertyRemoved")) {
- throw new FcpException("WebOfTrust Plugin did not reply with “PropertyRemoved” message!");
- }
- }
-
- //
- // PRIVATE METHODS
- //
-
- /**
- * Creates a map from each pair of parameters in the given array.
- *
- * @param parameters
- * The array of parameters
- * @return The map created from the array
- * @throws ArrayIndexOutOfBoundsException
- * if the given parameter array does not contains an even number
- * of elements
- */
- private Map<String, String> createParameters(String... parameters) throws ArrayIndexOutOfBoundsException {
- Map<String, String> parameterMap = new HashMap<String, String>();
- for (int index = 0; index < parameters.length; index += 2) {
- parameterMap.put(parameters[index], parameters[index + 1]);
- }
- return parameterMap;
- }
-
- /**
- * Wrapper around a web-of-trust identity.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- public static class Identity {
-
- /** The identity’s identifier. */
- private final String identifier;
-
- /** The identity’s nickname. */
- private final String nickname;
-
- /** The identity’s request URI. */
- private final String requestUri;
-
- /**
- * Creates a new identity.
- *
- * @param identifier
- * The identifies of the identity
- * @param nickname
- * The nickname of the identity
- * @param requestUri
- * The request URI of the identity
- */
- public Identity(String identifier, String nickname, String requestUri) {
- this.identifier = identifier;
- this.nickname = nickname;
- this.requestUri = requestUri;
- }
-
- /**
- * Returns the identifier of this identity.
- *
- * @return This identity’s identifier
- */
- public String getIdentifier() {
- return identifier;
- }
-
- /**
- * Returns the nickname of this identity.
- *
- * @return This identity’s nickname
- */
- public String getNickname() {
- return nickname;
- }
-
- /**
- * Returns the request URI of this identity.
- *
- * @return This identity’s request URI
- */
- public String getRequestUri() {
- return requestUri;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals(Object obj) {
- if ((obj == null) || (obj.getClass() != this.getClass())) {
- return false;
- }
- Identity identity = (Identity) obj;
- return identifier.equals(identity.identifier);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode() {
- return identifier.hashCode();
- }
-
- }
-
- /**
- * Container for the trust given from one identity to another.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- public static class IdentityTrust {
-
- /** The trust given to the identity. */
- private final byte trust;
-
- /** The command for the trust value. */
- private final String comment;
-
- /**
- * Creates a new identity trust container.
- *
- * @param trust
- * The trust given to the identity
- * @param comment
- * The comment for the trust value
- */
- public IdentityTrust(byte trust, String comment) {
- this.trust = trust;
- this.comment = comment;
- }
-
- /**
- * Returns the trust value given to the identity.
- *
- * @return The trust value
- */
- public byte getTrust() {
- return trust;
- }
-
- /**
- * Returns the comment for the trust value.
- *
- * @return The comment for the trust value
- */
- public String getComment() {
- return comment;
- }
-
- }
-
- /**
- * Container that stores the trust that is calculated by taking all trustees
- * and their trust lists into account.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- public static class CalculatedTrust {
-
- /** The calculated trust value. */
- private final Byte trust;
-
- /** The calculated score value. */
- private final Integer score;
-
- /** The calculated rank. */
- private final Integer rank;
-
- /**
- * Creates a new calculated trust container.
- *
- * @param trust
- * The calculated trust value
- * @param score
- * The calculated score value
- * @param rank
- * The calculated rank of the
- */
- public CalculatedTrust(Byte trust, Integer score, Integer rank) {
- this.trust = trust;
- this.score = score;
- this.rank = rank;
- }
-
- /**
- * Returns the calculated trust value.
- *
- * @return The calculated trust value, or {@code null} if the trust
- * value is not known
- */
- public Byte getTrust() {
- return trust;
- }
-
- /**
- * Returns the calculated score value.
- *
- * @return The calculated score value, or {@code null} if the score
- * value is not known
- */
- public Integer getScore() {
- return score;
- }
-
- /**
- * Returns the calculated rank.
- *
- * @return The calculated rank, or {@code null} if the rank is not known
- */
- public Integer getRank() {
- return rank;
- }
-
- }
-
- /**
- * Wrapper around a web-of-trust own identity.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- public static class OwnIdentity extends Identity {
-
- /** The identity’s insert URI. */
- private final String insertUri;
-
- /**
- * Creates a new web-of-trust own identity.
- *
- * @param identifier
- * The identifier of the identity
- * @param nickname
- * The nickname of the identity
- * @param requestUri
- * The request URI of the identity
- * @param insertUri
- * The insert URI of the identity
- */
- public OwnIdentity(String identifier, String nickname, String requestUri, String insertUri) {
- super(identifier, nickname, requestUri);
- this.insertUri = insertUri;
- }
-
- /**
- * Returns the insert URI of this identity.
- *
- * @return This identity’s insert URI
- */
- public String getInsertUri() {
- return insertUri;
- }
-
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - AbstractListenerManager.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.event;
-
-import java.util.EventListener;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.Executor;
-
-import net.pterodactylus.util.thread.CurrentThreadExecutor;
-
-/**
- * Abstract implementation of a listener support class. The listener support
- * takes care of adding and removing {@link EventListener} implementations, and
- * subclasses are responsible for firing appropriate events.
- *
- * @param <S>
- * The type of the source
- *@param <L>
- * The type of the event listeners
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public abstract class AbstractListenerManager<S, L extends EventListener> {
-
- /** The source that emits the events. */
- private final S source;
-
- /** The list of listeners. */
- private final List<L> listeners = new CopyOnWriteArrayList<L>();
-
- /** Service that executes event threads. */
- private final Executor executor;
-
- /**
- * Creates a new listener support that emits events from the given source.
- *
- * @param source
- * The source of the events
- */
- public AbstractListenerManager(S source) {
- this(source, new CurrentThreadExecutor());
- }
-
- /**
- * Creates a new listener support that emits events from the given source.
- *
- * @param source
- * The source of the events
- * @param executor
- * The executor used to fire events
- */
- public AbstractListenerManager(S source, Executor executor) {
- this.source = source;
- this.executor = executor;
- }
-
- /**
- * Adds the given listener to the list of reigstered listeners.
- *
- * @param listener
- * The listener to add
- */
- public void addListener(L listener) {
- synchronized (listeners) {
- listeners.add(listener);
- }
- }
-
- /**
- * Removes the given listener from the list of registered listeners.
- *
- * @param listener
- * The listener to remove
- */
- public void removeListener(L listener) {
- synchronized (listeners) {
- listeners.remove(listener);
- }
- }
-
- //
- // PROTECTED METHODS
- //
-
- /**
- * Returns the source for the events.
- *
- * @return The event source
- */
- protected S getSource() {
- return source;
- }
-
- /**
- * Returns the executor for the event firing.
- *
- * @return The executor
- */
- protected Executor getExecutor() {
- return executor;
- }
-
- /**
- * Returns a list of all registered listeners. The returned list is a copy
- * of the original list so structural modifications will never occur when
- * using the returned list.
- *
- * @return The list of all registered listeners
- */
- protected List<L> getListeners() {
- return listeners;
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - Filter.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-package net.pterodactylus.util.filter;
-
-/**
- * Interface for a filter that determines whether a certain action can be
- * performed on an object based on its properties.
- *
- * @param <T>
- * The type of the filtered object
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public interface Filter<T> {
-
- /**
- * Runs the given object through this filter and return whether the object
- * matches this filter or not.
- *
- * @param object
- * The object to analyse
- * @return <code>true</code> if the object matched this filter,
- * <code>false</code> otherwise
- */
- public boolean filterObject(T object);
-
-}
+++ /dev/null
-/*
- * jFCPlib - Filters.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-package net.pterodactylus.util.filter;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * Defines various methods to filter {@link Collection}s.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class Filters {
-
- /**
- * Returns a list that contains only the elements from the given list that
- * match the given filter.
- *
- * @param <E>
- * The type of the list elements
- * @param list
- * The list to filter
- * @param listFilter
- * The list filter
- * @return The filtered list
- */
- public static <E> List<E> filteredList(List<E> list, Filter<E> listFilter) {
- List<E> filteredList = new ArrayList<E>();
- for (E element : list) {
- if (listFilter.filterObject(element)) {
- filteredList.add(element);
- }
- }
- return filteredList;
- }
-
- /**
- * Returns a set that contains only the elements from the given set that
- * match the given filter.
- *
- * @param <E>
- * The type of the set elements
- * @param set
- * The set to filter
- * @param setFilter
- * The set filter
- * @return The filtered set
- */
- public static <E> Set<E> filteredSet(Set<E> set, Filter<E> setFilter) {
- Set<E> filteredSet = new HashSet<E>();
- for (E element : set) {
- if (setFilter.filterObject(element)) {
- filteredSet.add(element);
- }
- }
- return filteredSet;
- }
-
- /**
- * Returns a map that contains only the elements from the given map that
- * match the given filter.
- *
- * @param <K>
- * The type of the map keys
- * @param <V>
- * The type of the map values
- * @param map
- * The map to filter
- * @param mapFilter
- * The map filter
- * @return The filtered map
- */
- public static <K, V> Map<K, V> filteredMap(Map<K, V> map, Filter<Entry<K, V>> mapFilter) {
- Map<K, V> filteredMap = new HashMap<K, V>();
- for (Entry<K, V> element : map.entrySet()) {
- if (mapFilter.filterObject(element)) {
- filteredMap.put(element.getKey(), element.getValue());
- }
- }
- return filteredMap;
- }
-
- /**
- * Returns a collection that contains only the elements from the given
- * collection that match the given filter.
- *
- * @param <K>
- * The type of the collection values
- * @param collection
- * The collection to filter
- * @param collectionFilter
- * The collection filter
- * @return The filtered collection
- */
- public static <K> Collection<K> filteredCollection(Collection<K> collection, Filter<K> collectionFilter) {
- return filteredList(new ArrayList<K>(collection), collectionFilter);
- }
-
- /**
- * Returns an iterator that contains only the elements from the given
- * iterator that match the given filter.
- *
- * @param <E>
- * The type of the iterator elements
- * @param iterator
- * The iterator to filter
- * @param iteratorFilter
- * The iterator filter
- * @return The filtered iterator
- */
- public static <E> Iterator<E> filteredIterator(final Iterator<E> iterator, final Filter<E> iteratorFilter) {
- return new Iterator<E>() {
-
- private boolean gotNextElement = false;
-
- private E nextElement;
-
- private void getNextElement() {
- if (gotNextElement) {
- return;
- }
- while (iterator.hasNext()) {
- nextElement = iterator.next();
- if (iteratorFilter.filterObject(nextElement)) {
- gotNextElement = true;
- break;
- }
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.util.Iterator#hasNext()
- */
- public boolean hasNext() {
- getNextElement();
- return gotNextElement;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.util.Iterator#next()
- */
- public E next() {
- getNextElement();
- if (!gotNextElement) {
- throw new NoSuchElementException("no more elements in iteration");
- }
- gotNextElement = false;
- return nextElement;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.util.Iterator#remove()
- */
- public void remove() {
- throw new UnsupportedOperationException("remove() not supported on this iteration");
- }
-
- };
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - CurrentThreadExecutor.java - Copyright © 2009 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.util.thread;
-
-import java.util.concurrent.Executor;
-
-/**
- * An {@link Executor} that executes {@link Runnable}s in the current thread.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class CurrentThreadExecutor implements Executor {
-
- /**
- * {@inheritDoc}
- *
- * @see java.util.concurrent.Executor#execute(java.lang.Runnable)
- */
- public void execute(Runnable command) {
- command.run();
- }
-
-}
+++ /dev/null
-/*
- * jFCPlib - UserObject.java - Copyright © 2009 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.util.thread;
-
-/**
- * Wrapper around an object that can be set and retrieved. Its primary use is as
- * a container for return values from anonymous classes.
- *
- * <pre>
- * final ObjectWrapper<Object> objectWrapper = new ObjectWrapper<Object>();
- * new Runnable() {
- * public void run() {
- * ...
- * objectWrapper.set(someResult);
- * }
- * }.run();
- * Object result = objectWrapper.get();
- * </pre>
- *
- * @param <T>
- * The type of the wrapped object
- * @author David ‘Bombe’ Roden <bombe@pterodactylus.net>
- */
-public class ObjectWrapper<T> {
-
- /** The wrapped object. */
- private volatile T wrappedObject;
-
- /**
- * Returns the wrapped object.
- *
- * @return The wrapped object
- */
- public T get() {
- return wrappedObject;
- }
-
- /**
- * Sets the wrapped object.
- *
- * @param wrappedObject
- * The wrapped object
- */
- public void set(T wrappedObject) {
- this.wrappedObject = wrappedObject;
- }
-
-}
--- /dev/null
+/*
+ * jFCPlib - FcpConnectionTest.java -
+ * Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+
+/**
+ * TODO
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+public class FcpConnectionTest extends FcpAdapter {
+
+ public static void main(String[] commandLine) throws IllegalStateException, IOException {
+ new FcpConnectionTest();
+ }
+
+ private FcpConnectionTest() throws IllegalStateException, IOException {
+ FcpConnection fcpConnection = new FcpConnection("wing");
+ fcpConnection.addFcpListener(this);
+ fcpConnection.connect();
+ ClientHello clientHello = new ClientHello("bug-test");
+ fcpConnection.sendMessage(clientHello);
+ ClientGet clientGet = new ClientGet("KSK@gpl.txt", "test");
+ fcpConnection.sendMessage(clientGet);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void receivedAllData(FcpConnection fcpConnection, AllData allData) {
+ System.out.println("AllData");
+ InputStream payloadInputStream = allData.getPayloadInputStream();
+ int r = 0;
+ byte[] buffer = new byte[1024];
+ try {
+ while ((r = payloadInputStream.read(buffer)) != -1) {
+ for (int i = 0; i < r; i++) {
+ System.out.print((char) buffer[i]);
+ }
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ }
+ fcpConnection.close();
+ }
+
+}
+++ /dev/null
-/*
- * jFCPlib - FcpConnectionTest.java -
- * Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.fcp;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-
-/**
- * TODO
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class FcpConnectionTest extends FcpAdapter {
-
- public static void main(String[] commandLine) throws IllegalStateException, IOException {
- new FcpConnectionTest();
- }
-
- private FcpConnectionTest() throws IllegalStateException, IOException {
- FcpConnection fcpConnection = new FcpConnection("wing");
- fcpConnection.addFcpListener(this);
- fcpConnection.connect();
- ClientHello clientHello = new ClientHello("bug-test");
- fcpConnection.sendMessage(clientHello);
- ClientGet clientGet = new ClientGet("KSK@gpl.txt", "test");
- fcpConnection.sendMessage(clientGet);
- }
-
- /**
- * {@inheritDoc}
- */
- public void receivedAllData(FcpConnection fcpConnection, AllData allData) {
- System.out.println("AllData");
- InputStream payloadInputStream = allData.getPayloadInputStream();
- int r = 0;
- byte[] buffer = new byte[1024];
- try {
- while ((r = payloadInputStream.read(buffer)) != -1) {
- for (int i = 0; i < r; i++) {
- System.out.print((char) buffer[i]);
- }
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- }
- fcpConnection.close();
- }
-
-}