From: David ‘Bombe’ Roden Date: Fri, 10 Jun 2016 16:45:51 +0000 (+0200) Subject: Merge branch 'release-0.1.4' X-Git-Tag: v0.1.4^0 X-Git-Url: https://git.pterodactylus.net/?p=jFCPlib.git;a=commitdiff_plain;h=fed333217dc45a47f6eabea6a5b29aed987cd160;hp=6065356598b699145344a1a873054f2e5b0d23ef Merge branch 'release-0.1.4' --- diff --git a/pom.xml b/pom.xml index 4309367..26dbf4c 100644 --- a/pom.xml +++ b/pom.xml @@ -2,14 +2,14 @@ 4.0.0 net.pterodactylus jFCPlib - 0.1.3 + 0.1.4 jFCPlib jar pterodactylus pterodactylus.net Maven Repository - scp://maven@maven.pterodactylus.net/home/maven/repository + scpexe://maven@maven.pterodactylus.net/home/maven/repository @@ -41,6 +41,13 @@ UTF-8 + + + org.apache.maven.wagon + wagon-ssh-external + 2.9 + + org.apache.maven.plugins diff --git a/src/main/java/net/pterodactylus/fcp/AddPeer.java b/src/main/java/net/pterodactylus/fcp/AddPeer.java index e9ad80d..696a017 100644 --- a/src/main/java/net/pterodactylus/fcp/AddPeer.java +++ b/src/main/java/net/pterodactylus/fcp/AddPeer.java @@ -46,6 +46,11 @@ public class AddPeer extends FcpMessage { setField("File", file); } + public AddPeer(String identifier, String file) { + this(file); + setField("Identifier", identifier); + } + /** * Creates a new “AddPeer” request that reads the noderef of the peer from * the given URL. @@ -58,6 +63,11 @@ public class AddPeer extends FcpMessage { setField("URL", String.valueOf(url)); } + public AddPeer(String identifier, URL url) { + this(url); + setField("Identifier", identifier); + } + /** * Creates a new “AddPeer” request that adds the peer given by the noderef. * @@ -69,6 +79,11 @@ public class AddPeer extends FcpMessage { setNodeRef(nodeRef); } + public AddPeer(String identifier, NodeRef nodeRef) { + this(nodeRef); + setField("Identifier", identifier); + } + // // PRIVATE METHODS // @@ -80,7 +95,7 @@ public class AddPeer extends FcpMessage { * The noderef of the peer */ private void setNodeRef(NodeRef nodeRef) { - setField("lastGoodVersion", nodeRef.getLastGoodVersion().toString()); + setField("lastGoodVersion", String.valueOf(nodeRef.getLastGoodVersion())); setField("opennet", String.valueOf(nodeRef.isOpennet())); setField("identity", nodeRef.getIdentity()); setField("myName", nodeRef.getMyName()); diff --git a/src/main/java/net/pterodactylus/fcp/AllData.java b/src/main/java/net/pterodactylus/fcp/AllData.java index b4daa27..621e993 100644 --- a/src/main/java/net/pterodactylus/fcp/AllData.java +++ b/src/main/java/net/pterodactylus/fcp/AllData.java @@ -44,7 +44,7 @@ public class AllData extends BaseMessage implements Identifiable { * @param payloadInputStream * The payload */ - AllData(FcpMessage receivedMessage, InputStream payloadInputStream) { + public AllData(FcpMessage receivedMessage, InputStream payloadInputStream) { super(receivedMessage); this.payloadInputStream = payloadInputStream; } diff --git a/src/main/java/net/pterodactylus/fcp/BaseMessage.java b/src/main/java/net/pterodactylus/fcp/BaseMessage.java index a5ea020..cca7d67 100644 --- a/src/main/java/net/pterodactylus/fcp/BaseMessage.java +++ b/src/main/java/net/pterodactylus/fcp/BaseMessage.java @@ -57,7 +57,7 @@ public class BaseMessage { * @return The content of the field, or null if there is no * such field */ - protected String getField(String field) { + public String getField(String field) { return receivedMessage.getField(field); } @@ -67,7 +67,7 @@ public class BaseMessage { * @see FcpMessage#getFields() * @return All fields from the message */ - protected Map getFields() { + public Map getFields() { return receivedMessage.getFields(); } diff --git a/src/main/java/net/pterodactylus/fcp/ClientGet.java b/src/main/java/net/pterodactylus/fcp/ClientGet.java index 1126824..d340cf0 100644 --- a/src/main/java/net/pterodactylus/fcp/ClientGet.java +++ b/src/main/java/net/pterodactylus/fcp/ClientGet.java @@ -131,6 +131,10 @@ public class ClientGet extends FcpMessage { setField("PriorityClass", String.valueOf(priority)); } + public void setRealTimeFlag(boolean realTimeFlag) { + setField("RealTimeFlag", String.valueOf(realTimeFlag)); + } + /** * Sets the persistence of the request. * diff --git a/src/main/java/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java b/src/main/java/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java index db0ff0d..14775ae 100644 --- a/src/main/java/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java +++ b/src/main/java/net/pterodactylus/fcp/CloseConnectionDuplicateClientName.java @@ -32,7 +32,7 @@ public class CloseConnectionDuplicateClientName extends BaseMessage { * @param receivedMessage * The received message */ - CloseConnectionDuplicateClientName(FcpMessage receivedMessage) { + public CloseConnectionDuplicateClientName(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/ConfigData.java b/src/main/java/net/pterodactylus/fcp/ConfigData.java index 4eb7954..c05eb9f 100644 --- a/src/main/java/net/pterodactylus/fcp/ConfigData.java +++ b/src/main/java/net/pterodactylus/fcp/ConfigData.java @@ -32,7 +32,7 @@ public class ConfigData extends BaseMessage { * @param receivedMessage * The received message */ - ConfigData(FcpMessage receivedMessage) { + public ConfigData(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/DataFound.java b/src/main/java/net/pterodactylus/fcp/DataFound.java index 742f6ac..c00709a 100644 --- a/src/main/java/net/pterodactylus/fcp/DataFound.java +++ b/src/main/java/net/pterodactylus/fcp/DataFound.java @@ -33,7 +33,7 @@ public class DataFound extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - DataFound(FcpMessage receivedMessage) { + public DataFound(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/EndListPeerNotes.java b/src/main/java/net/pterodactylus/fcp/EndListPeerNotes.java index 31a52af..88e8525 100644 --- a/src/main/java/net/pterodactylus/fcp/EndListPeerNotes.java +++ b/src/main/java/net/pterodactylus/fcp/EndListPeerNotes.java @@ -33,7 +33,7 @@ public class EndListPeerNotes extends BaseMessage { * @param fcpMessage * The received message */ - EndListPeerNotes(FcpMessage fcpMessage) { + public EndListPeerNotes(FcpMessage fcpMessage) { super(fcpMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/EndListPeers.java b/src/main/java/net/pterodactylus/fcp/EndListPeers.java index bb98f23..5a505d0 100644 --- a/src/main/java/net/pterodactylus/fcp/EndListPeers.java +++ b/src/main/java/net/pterodactylus/fcp/EndListPeers.java @@ -31,7 +31,7 @@ public class EndListPeers extends BaseMessage implements Identifiable { * @param receivedMessage * The message that was received */ - EndListPeers(FcpMessage receivedMessage) { + public EndListPeers(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/EndListPersistentRequests.java b/src/main/java/net/pterodactylus/fcp/EndListPersistentRequests.java index baa8de2..702cc95 100644 --- a/src/main/java/net/pterodactylus/fcp/EndListPersistentRequests.java +++ b/src/main/java/net/pterodactylus/fcp/EndListPersistentRequests.java @@ -33,7 +33,7 @@ public class EndListPersistentRequests extends BaseMessage { * @param receivedMessage * The received message */ - EndListPersistentRequests(FcpMessage receivedMessage) { + public EndListPersistentRequests(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/FCPPluginMessage.java b/src/main/java/net/pterodactylus/fcp/FCPPluginMessage.java index 99cb0d0..92a9949 100644 --- a/src/main/java/net/pterodactylus/fcp/FCPPluginMessage.java +++ b/src/main/java/net/pterodactylus/fcp/FCPPluginMessage.java @@ -18,6 +18,8 @@ package net.pterodactylus.fcp; +import java.io.InputStream; + /** * An “CPPluginMessage” sends a message with custom parameters and (optional) * payload to a plugin. @@ -27,24 +29,23 @@ package net.pterodactylus.fcp; public class FCPPluginMessage extends FcpMessage { /** - * Creates a new “FCPPluginMessage” message for the given plugin. - * - * @param pluginClass - * The name of the plugin class + * @deprecated Use {@link #FCPPluginMessage(String, String)} instead */ + @Deprecated public FCPPluginMessage(String pluginClass) { super("FCPPluginMessage"); setField("PluginName", pluginClass); } + public FCPPluginMessage(String identifier, String pluginClass) { + this(pluginClass); + setField("Identifier", identifier); + } + /** - * 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 + * @deprecated Use {@link #FCPPluginMessage(String, String)} instead */ + @Deprecated public void setIdentifier(String identifier) { setField("Identifier", identifier); } @@ -53,24 +54,25 @@ public class FCPPluginMessage extends FcpMessage { * Sets a custom parameter for the plugin. * * @param key - * The key of the parameter + * The key of the parameter * @param value - * The value of the parameter + * 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 + * @deprecated Use {@link #setData(InputStream, long)} instead */ + @Deprecated public void setDataLength(long dataLength) { setField("DataLength", String.valueOf(dataLength)); } + public void setData(InputStream payloadInputStream, long dataLength) { + setPayloadInputStream(payloadInputStream); + setDataLength(dataLength); + } + } diff --git a/src/main/java/net/pterodactylus/fcp/FCPPluginReply.java b/src/main/java/net/pterodactylus/fcp/FCPPluginReply.java index 44e96ba..0ed55f0 100644 --- a/src/main/java/net/pterodactylus/fcp/FCPPluginReply.java +++ b/src/main/java/net/pterodactylus/fcp/FCPPluginReply.java @@ -42,7 +42,7 @@ public class FCPPluginReply extends BaseMessage implements Identifiable { * @param payloadInputStream * The optional input stream for the payload */ - FCPPluginReply(FcpMessage receivedMessage, InputStream payloadInputStream) { + public FCPPluginReply(FcpMessage receivedMessage, InputStream payloadInputStream) { super(receivedMessage); this.payloadInputStream = payloadInputStream; } diff --git a/src/main/java/net/pterodactylus/fcp/FcpAdapter.java b/src/main/java/net/pterodactylus/fcp/FcpAdapter.java index 063d363..0d0debc 100644 --- a/src/main/java/net/pterodactylus/fcp/FcpAdapter.java +++ b/src/main/java/net/pterodactylus/fcp/FcpAdapter.java @@ -253,6 +253,11 @@ public class FcpAdapter implements FcpListener { /* empty. */ } + @Override + public void receivedSubscribedUSK(FcpConnection fcpConnection, SubscribedUSK subscribedUSK) { + /* empty. */ + } + /** * {@inheritDoc} */ @@ -273,6 +278,11 @@ public class FcpAdapter implements FcpListener { * {@inheritDoc} */ @Override + public void receivedPluginRemoved(FcpConnection fcpConnection, PluginRemoved pluginRemoved) { + /* empty. */ + } + + @Override public void receivedFCPPluginReply(FcpConnection fcpConnection, FCPPluginReply fcpPluginReply) { /* empty. */ } diff --git a/src/main/java/net/pterodactylus/fcp/FcpConnection.java b/src/main/java/net/pterodactylus/fcp/FcpConnection.java index 66377a2..b7b99bf 100644 --- a/src/main/java/net/pterodactylus/fcp/FcpConnection.java +++ b/src/main/java/net/pterodactylus/fcp/FcpConnection.java @@ -31,6 +31,8 @@ import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; +import net.pterodactylus.fcp.FcpUtils.TempInputStream; + /** * An FCP connection to a Freenet node. * @@ -156,6 +158,10 @@ public class FcpConnection implements Closeable { fcpListenerManager.removeListener(fcpListener); } + public synchronized boolean isClosed() { + return connectionHandler == null; + } + // // ACTIONS // @@ -223,7 +229,7 @@ public class FcpConnection implements Closeable { * @param fcpMessage * The received message */ - void handleMessage(FcpMessage fcpMessage) { + void handleMessage(FcpMessage fcpMessage) throws IOException{ logger.fine("received message: " + fcpMessage.getName()); String messageName = fcpMessage.getName(); countMessage(messageName); @@ -261,16 +267,13 @@ public class FcpConnection implements Closeable { fcpListenerManager.fireReceivedDataFound(new DataFound(fcpMessage)); } else if ("SubscribedUSKUpdate".equals(messageName)) { fcpListenerManager.fireReceivedSubscribedUSKUpdate(new SubscribedUSKUpdate(fcpMessage)); + } else if ("SubscribedUSK".equals(messageName)) { + fcpListenerManager.fireReceivedSubscribedUSK(new SubscribedUSK(fcpMessage)); } else if ("IdentifierCollision".equals(messageName)) { fcpListenerManager.fireReceivedIdentifierCollision(new IdentifierCollision(fcpMessage)); } else if ("AllData".equals(messageName)) { - LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength"))); + InputStream 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)) { @@ -288,15 +291,12 @@ public class FcpConnection implements Closeable { } else if ("UnknownNodeIdentifier".equals(messageName)) { fcpListenerManager.fireReceivedUnknownNodeIdentifier(new UnknownNodeIdentifier(fcpMessage)); } else if ("FCPPluginReply".equals(messageName)) { - LimitedInputStream payloadInputStream = getInputStream(FcpUtils.safeParseLong(fcpMessage.getField("DataLength"))); + InputStream 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 ("PluginRemoved".equals(messageName)) { + fcpListenerManager.fireReceivedPluginRemoved(new PluginRemoved(fcpMessage)); } else if ("NodeData".equals(messageName)) { fcpListenerManager.fireReceivedNodeData(new NodeData(fcpMessage)); } else if ("TestDDAReply".equals(messageName)) { @@ -356,142 +356,8 @@ public class FcpConnection implements Closeable { 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 - * length bytes from the given input stream. - * - * @param inputStream - * The input stream - * @param length - * The number of bytes to read - */ - public LimitedInputStream(InputStream inputStream, long length) { - super(inputStream); - remaining = length; - } - - /** - * @see java.io.FilterInputStream#available() - */ - @Override - public synchronized int available() throws IOException { - if (remaining == 0) { - return 0; - } - return (int) Math.min(super.available(), Math.min(Integer.MAX_VALUE, remaining)); - } - - /** - * @see java.io.FilterInputStream#read() - */ - @Override - public synchronized int read() throws IOException { - int read = -1; - if (remaining > 0) { - read = super.read(); - remaining--; - } - return read; - } - - /** - * @see java.io.FilterInputStream#read(byte[], int, int) - */ - @Override - public synchronized int read(byte[] b, int off, int len) throws IOException { - if (remaining == 0) { - return -1; - } - int toCopy = (int) Math.min(len, Math.min(remaining, Integer.MAX_VALUE)); - int read = super.read(b, off, toCopy); - remaining -= read; - return read; - } - - /** - * @see java.io.FilterInputStream#skip(long) - */ - @Override - public synchronized long skip(long n) throws IOException { - if ((n < 0) || (remaining == 0)) { - return 0; - } - long skipped = super.skip(Math.min(n, remaining)); - remaining -= skipped; - return skipped; - } - - /** - * {@inheritDoc} This method does nothing, as {@link #mark(int)} and - * {@link #reset()} are not supported. - * - * @see java.io.FilterInputStream#mark(int) - */ - @Override - public synchronized void mark(int readlimit) { - /* do nothing. */ - } - - /** - * {@inheritDoc} - * - * @see java.io.FilterInputStream#markSupported() - * @return false - */ - @Override - public boolean markSupported() { - return false; - } - - /** - * {@inheritDoc} This method does nothing, as {@link #mark(int)} and - * {@link #reset()} are not supported. - * - * @see java.io.FilterInputStream#reset() - */ - @Override - public synchronized 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); - } - } - + private synchronized InputStream getInputStream(long dataLength) throws IOException { + return new TempInputStream(remoteInputStream, dataLength); } } diff --git a/src/main/java/net/pterodactylus/fcp/FcpConnectionHandler.java b/src/main/java/net/pterodactylus/fcp/FcpConnectionHandler.java index 36be123..256efef 100644 --- a/src/main/java/net/pterodactylus/fcp/FcpConnectionHandler.java +++ b/src/main/java/net/pterodactylus/fcp/FcpConnectionHandler.java @@ -18,6 +18,7 @@ package net.pterodactylus.fcp; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; @@ -76,8 +77,9 @@ class FcpConnectionHandler implements Runnable { } try { String line = readLine(); - logger.log(Level.FINEST, "read line: %1$s", line); + logger.log(Level.FINEST, String.format("read line: %1$s", line)); if (line == null) { + throwable = new EOFException(); break; } if (line.length() == 0) { diff --git a/src/main/java/net/pterodactylus/fcp/FcpListener.java b/src/main/java/net/pterodactylus/fcp/FcpListener.java index 02eeed5..b96885f 100644 --- a/src/main/java/net/pterodactylus/fcp/FcpListener.java +++ b/src/main/java/net/pterodactylus/fcp/FcpListener.java @@ -309,6 +309,8 @@ public interface FcpListener extends EventListener { */ public void receivedPersistentRequestRemoved(FcpConnection fcpConnection, PersistentRequestRemoved persistentRequestRemoved); + void receivedSubscribedUSK(FcpConnection fcpConnection, SubscribedUSK subscribedUSK); + /** * Notifies a listener that a “SubscribedUSKUpdate” message was received. * @@ -329,6 +331,8 @@ public interface FcpListener extends EventListener { */ public void receivedPluginInfo(FcpConnection fcpConnection, PluginInfo pluginInfo); + void receivedPluginRemoved(FcpConnection fcpConnection, PluginRemoved pluginRemoved); + /** * Notifies a listener that an “FCPPluginReply“ message was received. * diff --git a/src/main/java/net/pterodactylus/fcp/FcpListenerManager.java b/src/main/java/net/pterodactylus/fcp/FcpListenerManager.java index 7969da1..a25f3bf 100644 --- a/src/main/java/net/pterodactylus/fcp/FcpListenerManager.java +++ b/src/main/java/net/pterodactylus/fcp/FcpListenerManager.java @@ -438,6 +438,12 @@ public class FcpListenerManager { } } + public void fireReceivedSubscribedUSK(SubscribedUSK subscribedUSK) { + for (FcpListener fcpListener : getListeners()) { + fcpListener.receivedSubscribedUSK(getSource(), subscribedUSK); + } + } + /** * Notifies all listeners that a “SubscribedUSKUpdate” message was * received. @@ -466,6 +472,12 @@ public class FcpListenerManager { } } + public void fireReceivedPluginRemoved(PluginRemoved pluginRemoved) { + for (FcpListener fcpListener : getListeners()) { + fcpListener.receivedPluginRemoved(getSource(), pluginRemoved); + } + } + /** * Notifies all listeners that an “FCPPluginReply” message was received. * diff --git a/src/main/java/net/pterodactylus/fcp/FcpMessage.java b/src/main/java/net/pterodactylus/fcp/FcpMessage.java index ed4ae46..d9fff9b 100644 --- a/src/main/java/net/pterodactylus/fcp/FcpMessage.java +++ b/src/main/java/net/pterodactylus/fcp/FcpMessage.java @@ -110,6 +110,11 @@ public class FcpMessage implements Iterable { fields.put(field, value); } + public FcpMessage put(String field, String value) { + setField(field, value); + return this; + } + /** * Returns the value of the given field. * diff --git a/src/main/java/net/pterodactylus/fcp/FcpUtils.java b/src/main/java/net/pterodactylus/fcp/FcpUtils.java index 415cf1a..26a407c 100644 --- a/src/main/java/net/pterodactylus/fcp/FcpUtils.java +++ b/src/main/java/net/pterodactylus/fcp/FcpUtils.java @@ -268,7 +268,9 @@ public class FcpUtils { throw new EOFException("stream reached eof"); } destination.write(buffer, 0, read); - remaining -= read; + if (remaining > 0) { + remaining -= read; + } } } diff --git a/src/main/java/net/pterodactylus/fcp/FinishedCompression.java b/src/main/java/net/pterodactylus/fcp/FinishedCompression.java index 91c0341..d6c3ac7 100644 --- a/src/main/java/net/pterodactylus/fcp/FinishedCompression.java +++ b/src/main/java/net/pterodactylus/fcp/FinishedCompression.java @@ -33,7 +33,7 @@ public class FinishedCompression extends BaseMessage implements Identifiable { * @param receivedMessage * The message that was recevied */ - FinishedCompression(FcpMessage receivedMessage) { + public FinishedCompression(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/FreenetBase64.java b/src/main/java/net/pterodactylus/fcp/FreenetBase64.java new file mode 100644 index 0000000..4c3422d --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/FreenetBase64.java @@ -0,0 +1,90 @@ +package net.pterodactylus.fcp; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * Freenet-specific Base64 implementation. + * + * @author David ‘Bombe’ Roden + */ +public class FreenetBase64 { + + private static final char[] FREENET_BASE64_ALPHABET = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~-".toCharArray(); + private static final int[] REVERSE_FREENET_BASE64_ALPHABET = reverse(FREENET_BASE64_ALPHABET); + + private static int[] reverse(char[] alphabet) { + String alphabetString = new String(alphabet); + int[] reversedAlphabet = new int[128]; + for (int i = 0; i < 128; i++) { + if (alphabetString.indexOf(i) > -1) { + reversedAlphabet[i] = alphabetString.indexOf(i); + } else { + reversedAlphabet[i] = -1; + } + } + return reversedAlphabet; + } + + public String encode(byte[] data) { + StringBuilder result = new StringBuilder(); + int currentValue = 0; + int index = 0; + while (index < data.length) { + currentValue = (currentValue << 8) | data[index]; + if (index % 3 == 2) { + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 18) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 12) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 6) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[currentValue & 0x3f]); + } + index++; + } + if (index % 3 == 1) { + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 2) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[(currentValue << 4) & 0x3f]); + result.append("=="); + } else if (index % 3 == 2) { + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 10) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 4) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[(currentValue << 2) & 0x3f]); + result.append("="); + } + return result.toString(); + } + + public byte[] decode(String data) { + ByteArrayOutputStream dataOutput = new ByteArrayOutputStream(data.length() * 3 / 4); + try { + int currentValue = 0; + int index = 0; + for (char c : data.toCharArray()) { + if (c == '=') { + break; + } + currentValue = (currentValue << 6) | REVERSE_FREENET_BASE64_ALPHABET[c]; + if (index % 4 == 3) { + dataOutput.write((currentValue >> 16) & 0xff); + dataOutput.write((currentValue >> 8) & 0xff); + dataOutput.write(currentValue & 0xff); + } + index++; + } + if (index % 4 == 2) { + dataOutput.write((currentValue >> 4) & 0xff); + } else if (index % 4 == 3) { + dataOutput.write((currentValue >> 10) & 0xff); + dataOutput.write((currentValue >> 2) & 0xff); + } + return dataOutput.toByteArray(); + } finally { + try { + dataOutput.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/GetConfig.java b/src/main/java/net/pterodactylus/fcp/GetConfig.java index 230a790..3e381bf 100644 --- a/src/main/java/net/pterodactylus/fcp/GetConfig.java +++ b/src/main/java/net/pterodactylus/fcp/GetConfig.java @@ -33,6 +33,11 @@ public class GetConfig extends FcpMessage { super("GetConfig"); } + public GetConfig(String identifer) { + this(); + setField("Identifier", identifer); + } + /** * Sets whether the {@link ConfigData} result message shall include the * current values. diff --git a/src/main/java/net/pterodactylus/fcp/GetFailed.java b/src/main/java/net/pterodactylus/fcp/GetFailed.java index 01ec1c8..10c22b5 100644 --- a/src/main/java/net/pterodactylus/fcp/GetFailed.java +++ b/src/main/java/net/pterodactylus/fcp/GetFailed.java @@ -38,7 +38,7 @@ public class GetFailed extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - GetFailed(FcpMessage receivedMessage) { + public GetFailed(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/GetNode.java b/src/main/java/net/pterodactylus/fcp/GetNode.java index 3419860..0a84acf 100644 --- a/src/main/java/net/pterodactylus/fcp/GetNode.java +++ b/src/main/java/net/pterodactylus/fcp/GetNode.java @@ -49,7 +49,14 @@ public class GetNode extends FcpMessage { * true to include volatile data in the noderef */ public GetNode(Boolean giveOpennetRef, Boolean withPrivate, Boolean withVolatile) { + this(null, giveOpennetRef, withPrivate, withVolatile); + } + + public GetNode(String identifier, Boolean giveOpennetRef, Boolean withPrivate, Boolean withVolatile) { super("GetNode"); + if (identifier != null) { + setField("Identifier", identifier); + } if (giveOpennetRef != null) { setField("GiveOpennetRef", String.valueOf(giveOpennetRef)); } diff --git a/src/main/java/net/pterodactylus/fcp/GetPluginInfo.java b/src/main/java/net/pterodactylus/fcp/GetPluginInfo.java index 8ad5392..12e446e 100644 --- a/src/main/java/net/pterodactylus/fcp/GetPluginInfo.java +++ b/src/main/java/net/pterodactylus/fcp/GetPluginInfo.java @@ -26,20 +26,20 @@ package net.pterodactylus.fcp; */ 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) { + public GetPluginInfo(String identifier) { super("GetPluginInfo"); - setField("PluginName", pluginName); setField("Identifier", identifier); } + public GetPluginInfo(String pluginName, String identifier) { + this(identifier); + setField("PluginName", pluginName); + } + + public void setPluginName(String pluginName) { + setField("PluginName", pluginName); + } + /** * Sets whether detailed information about the plugin is wanted. * diff --git a/src/main/java/net/pterodactylus/fcp/IdentifierCollision.java b/src/main/java/net/pterodactylus/fcp/IdentifierCollision.java index 5ce6f4a..bd28d67 100644 --- a/src/main/java/net/pterodactylus/fcp/IdentifierCollision.java +++ b/src/main/java/net/pterodactylus/fcp/IdentifierCollision.java @@ -33,7 +33,7 @@ public class IdentifierCollision extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - IdentifierCollision(FcpMessage receivedMessage) { + public IdentifierCollision(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/Key.java b/src/main/java/net/pterodactylus/fcp/Key.java new file mode 100644 index 0000000..f16b752 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/Key.java @@ -0,0 +1,20 @@ +package net.pterodactylus.fcp; + +/** + * Non-validating wrapper around a Freenet key. + * + * @author David ‘Bombe’ Roden + */ +public class Key { + + private final String key; + + public Key(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/ListPeer.java b/src/main/java/net/pterodactylus/fcp/ListPeer.java index e96a389..2984e6c 100644 --- a/src/main/java/net/pterodactylus/fcp/ListPeer.java +++ b/src/main/java/net/pterodactylus/fcp/ListPeer.java @@ -35,7 +35,14 @@ public class ListPeer extends FcpMessage { * The identifier of the node to get details about */ public ListPeer(String nodeIdentifier) { + this(null, nodeIdentifier); + } + + public ListPeer(String identifier, String nodeIdentifier) { super("ListPeer"); + if (identifier != null) { + setField("Identifier", identifier); + } setField("NodeIdentifier", nodeIdentifier); } diff --git a/src/main/java/net/pterodactylus/fcp/ListPeerNotes.java b/src/main/java/net/pterodactylus/fcp/ListPeerNotes.java index 82e3399..9080830 100644 --- a/src/main/java/net/pterodactylus/fcp/ListPeerNotes.java +++ b/src/main/java/net/pterodactylus/fcp/ListPeerNotes.java @@ -38,4 +38,9 @@ public class ListPeerNotes extends FcpMessage { setField("NodeIdentifier", nodeIdentifier); } + public ListPeerNotes(String identifier, String nodeIdentifier) { + this(nodeIdentifier); + setField("Identifier", identifier); + } + } diff --git a/src/main/java/net/pterodactylus/fcp/LoadPlugin.java b/src/main/java/net/pterodactylus/fcp/LoadPlugin.java new file mode 100644 index 0000000..9eb2d2d --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/LoadPlugin.java @@ -0,0 +1,47 @@ +package net.pterodactylus.fcp; + +/** + * The “LoadPlugin” message is used to load a plugin. + * + * @author David ‘Bombe’ Roden + */ +public class LoadPlugin extends FcpMessage { + + public enum UrlType { + + OFFICIAL, + FILE, + FREENET, + URL + + } + + public enum OfficialSource { + + FREENET, + HTTPS + + } + + public LoadPlugin(String identifier) { + super("LoadPlugin"); + setField("Identifier", identifier); + } + + public void setPluginUrl(String pluginUrl) { + setField("PluginURL", pluginUrl); + } + + public void setUrlType(UrlType urlType) { + setField("URLType", urlType.toString().toLowerCase()); + } + + public void setStore(boolean store) { + setField("Store", String.valueOf(store)); + } + + public void setOfficialSource(OfficialSource officialSource) { + setField("OfficialSource", officialSource.toString().toLowerCase()); + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/ModifyConfig.java b/src/main/java/net/pterodactylus/fcp/ModifyConfig.java index 412b818..687ee16 100644 --- a/src/main/java/net/pterodactylus/fcp/ModifyConfig.java +++ b/src/main/java/net/pterodactylus/fcp/ModifyConfig.java @@ -32,6 +32,11 @@ public class ModifyConfig extends FcpMessage { super("ModifyConfig"); } + public ModifyConfig(String identifier) { + this(); + setField("Identifier", identifier); + } + /** * Sets the option with the given name to the given value. * diff --git a/src/main/java/net/pterodactylus/fcp/ModifyPeer.java b/src/main/java/net/pterodactylus/fcp/ModifyPeer.java index dfc5aa2..f1905e7 100644 --- a/src/main/java/net/pterodactylus/fcp/ModifyPeer.java +++ b/src/main/java/net/pterodactylus/fcp/ModifyPeer.java @@ -25,32 +25,45 @@ package net.pterodactylus.fcp; */ 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 identifier, String nodeIdentifier) { + super("ModifyPeer"); + setField("Identifier", identifier); + setField("NodeIdentifier", nodeIdentifier); + } + + @Deprecated public ModifyPeer(String nodeIdentifier, Boolean allowLocalAddresses, Boolean disabled, Boolean listenOnly) { super("ModifyPeer"); setField("NodeIdentifier", nodeIdentifier); if (allowLocalAddresses != null) { - setField("AllowLocalAddresses", String.valueOf(allowLocalAddresses)); + setAllowLocalAddresses(allowLocalAddresses); } if (disabled != null) { - setField("IsDisabled", String.valueOf(disabled)); + setEnabled(!disabled); } if (listenOnly != null) { - setField("IsListenOnly", String.valueOf(listenOnly)); + setListenOnly(listenOnly); } } + public void setAllowLocalAddresses(boolean allowLocalAddresses) { + setField("AllowLocalAddresses", String.valueOf(allowLocalAddresses)); + } + + public void setEnabled(boolean enabled) { + setField("IsDisabled", String.valueOf(!enabled)); + } + + public void setListenOnly(boolean listenOnly) { + setField("IsListenOnly", String.valueOf(listenOnly)); + } + + public void setBurstOnly(boolean burstOnly) { + setField("IsBurstOnly", String.valueOf(burstOnly)); + } + + public void setIgnoreSource(boolean ignoreSource) { + setField("IgnoreSourcePort", String.valueOf(ignoreSource)); + } + } diff --git a/src/main/java/net/pterodactylus/fcp/ModifyPeerNote.java b/src/main/java/net/pterodactylus/fcp/ModifyPeerNote.java index 6fcc088..c7338ff 100644 --- a/src/main/java/net/pterodactylus/fcp/ModifyPeerNote.java +++ b/src/main/java/net/pterodactylus/fcp/ModifyPeerNote.java @@ -18,6 +18,8 @@ package net.pterodactylus.fcp; +import com.google.common.base.Charsets; + /** * The “ModifyPeerNote” command modifies a peer note. * @@ -25,25 +27,28 @@ package net.pterodactylus.fcp; */ 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 - */ + private static final FreenetBase64 BASE64_ENCODER = new FreenetBase64(); + + public ModifyPeerNote(String identifier, String nodeIdentifier) { + super("ModifyPeerNote"); + setField("Identifier", identifier); + setField("NodeIdentifier", nodeIdentifier); + } + + @Deprecated public ModifyPeerNote(String nodeIdentifier, String noteText, int peerNoteType) { - super("ModifyPeer"); + super("ModifyPeerNote"); setField("NodeIdentifier", nodeIdentifier); setField("NoteText", noteText); setField("PeerNoteType", String.valueOf(peerNoteType)); } + public void setNoteText(String noteText) { + setField("NoteText", BASE64_ENCODER.encode(noteText.getBytes(Charsets.UTF_8))); + } + + public void setPeerNoteType(PeerNoteType peerNoteType) { + setField("PeerNoteType", peerNoteType.toString()); + } + } diff --git a/src/main/java/net/pterodactylus/fcp/NodeData.java b/src/main/java/net/pterodactylus/fcp/NodeData.java index f73bbd5..5800172 100644 --- a/src/main/java/net/pterodactylus/fcp/NodeData.java +++ b/src/main/java/net/pterodactylus/fcp/NodeData.java @@ -34,7 +34,7 @@ public class NodeData extends BaseMessage { * @param receivedMessage * The received message */ - NodeData(FcpMessage receivedMessage) { + public NodeData(FcpMessage receivedMessage) { super(receivedMessage); nodeRef = new NodeRef(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/NodeHello.java b/src/main/java/net/pterodactylus/fcp/NodeHello.java index 7409d9b..32a4e33 100644 --- a/src/main/java/net/pterodactylus/fcp/NodeHello.java +++ b/src/main/java/net/pterodactylus/fcp/NodeHello.java @@ -31,7 +31,7 @@ public class NodeHello extends BaseMessage { * @param receivedMessage * The received FCP message */ - NodeHello(FcpMessage receivedMessage) { + public NodeHello(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/Peer.java b/src/main/java/net/pterodactylus/fcp/Peer.java index df1c8f0..72925cb 100644 --- a/src/main/java/net/pterodactylus/fcp/Peer.java +++ b/src/main/java/net/pterodactylus/fcp/Peer.java @@ -36,7 +36,7 @@ public class Peer extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - Peer(FcpMessage receivedMessage) { + public Peer(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/PeerNote.java b/src/main/java/net/pterodactylus/fcp/PeerNote.java index 67cdfa6..034e40f 100644 --- a/src/main/java/net/pterodactylus/fcp/PeerNote.java +++ b/src/main/java/net/pterodactylus/fcp/PeerNote.java @@ -18,6 +18,8 @@ package net.pterodactylus.fcp; +import com.google.common.base.Charsets; + /** * The “PeerNote” message contains a private note that has been entered for a * darknet peer. @@ -26,6 +28,8 @@ package net.pterodactylus.fcp; */ public class PeerNote extends BaseMessage { + private static final FreenetBase64 BASE64_DECODER = new FreenetBase64(); + /** The type for base64 encoded peer notes. */ public static final int TYPE_PRIVATE_PEER_NOTE = 1; @@ -35,7 +39,7 @@ public class PeerNote extends BaseMessage { * @param receivedMessage * The received message */ - PeerNote(FcpMessage receivedMessage) { + public PeerNote(FcpMessage receivedMessage) { super(receivedMessage); } @@ -54,7 +58,7 @@ public class PeerNote extends BaseMessage { * @return The note text */ public String getNoteText() { - return getField("NoteText"); + return new String(BASE64_DECODER.decode(getField("NoteText")), Charsets.UTF_8); } /** diff --git a/src/main/java/net/pterodactylus/fcp/PeerNoteType.java b/src/main/java/net/pterodactylus/fcp/PeerNoteType.java new file mode 100644 index 0000000..7ebede3 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/PeerNoteType.java @@ -0,0 +1,23 @@ +package net.pterodactylus.fcp; + +/** + * All possible peer note types. + * + * @author David ‘Bombe’ Roden + */ +public enum PeerNoteType { + + PRIVATE_DARKNET_COMMENT(1); + + private int value; + + PeerNoteType(int value) { + this.value = value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/PeerRemoved.java b/src/main/java/net/pterodactylus/fcp/PeerRemoved.java index 61aa08d..80da4b6 100644 --- a/src/main/java/net/pterodactylus/fcp/PeerRemoved.java +++ b/src/main/java/net/pterodactylus/fcp/PeerRemoved.java @@ -31,7 +31,7 @@ public class PeerRemoved extends BaseMessage { * @param receivedMessage * The received message */ - PeerRemoved(FcpMessage receivedMessage) { + public PeerRemoved(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/PersistentGet.java b/src/main/java/net/pterodactylus/fcp/PersistentGet.java index c7bfe20..7fc70a9 100644 --- a/src/main/java/net/pterodactylus/fcp/PersistentGet.java +++ b/src/main/java/net/pterodactylus/fcp/PersistentGet.java @@ -33,7 +33,7 @@ public class PersistentGet extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - PersistentGet(FcpMessage receivedMessage) { + public PersistentGet(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/PersistentPut.java b/src/main/java/net/pterodactylus/fcp/PersistentPut.java index 2dc8213..f1114ac 100644 --- a/src/main/java/net/pterodactylus/fcp/PersistentPut.java +++ b/src/main/java/net/pterodactylus/fcp/PersistentPut.java @@ -32,7 +32,7 @@ public class PersistentPut extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - PersistentPut(FcpMessage receivedMessage) { + public PersistentPut(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/PersistentPutDir.java b/src/main/java/net/pterodactylus/fcp/PersistentPutDir.java index b68c84c..4b668b3 100644 --- a/src/main/java/net/pterodactylus/fcp/PersistentPutDir.java +++ b/src/main/java/net/pterodactylus/fcp/PersistentPutDir.java @@ -34,7 +34,7 @@ public class PersistentPutDir extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - PersistentPutDir(FcpMessage receivedMessage) { + public PersistentPutDir(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/PersistentRequestModified.java b/src/main/java/net/pterodactylus/fcp/PersistentRequestModified.java index f1d2371..5b02624 100644 --- a/src/main/java/net/pterodactylus/fcp/PersistentRequestModified.java +++ b/src/main/java/net/pterodactylus/fcp/PersistentRequestModified.java @@ -33,7 +33,7 @@ public class PersistentRequestModified extends BaseMessage implements Identifiab * @param receivedMessage * The received message */ - PersistentRequestModified(FcpMessage receivedMessage) { + public PersistentRequestModified(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/PersistentRequestRemoved.java b/src/main/java/net/pterodactylus/fcp/PersistentRequestRemoved.java index c9ec826..4d15250 100644 --- a/src/main/java/net/pterodactylus/fcp/PersistentRequestRemoved.java +++ b/src/main/java/net/pterodactylus/fcp/PersistentRequestRemoved.java @@ -33,7 +33,7 @@ public class PersistentRequestRemoved extends BaseMessage implements Identifiabl * @param receivedMessage * The received message */ - PersistentRequestRemoved(FcpMessage receivedMessage) { + public PersistentRequestRemoved(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/PluginInfo.java b/src/main/java/net/pterodactylus/fcp/PluginInfo.java index fbce581..bf11be8 100644 --- a/src/main/java/net/pterodactylus/fcp/PluginInfo.java +++ b/src/main/java/net/pterodactylus/fcp/PluginInfo.java @@ -31,7 +31,7 @@ public class PluginInfo extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - PluginInfo(FcpMessage receivedMessage) { + public PluginInfo(FcpMessage receivedMessage) { super(receivedMessage); } @@ -60,7 +60,7 @@ public class PluginInfo extends BaseMessage implements Identifiable { * @return The original URI of the plugin */ public String getOriginalURI() { - return getField("OriginalUri"); + return getField("OriginUri"); } /** @@ -70,7 +70,18 @@ public class PluginInfo extends BaseMessage implements Identifiable { * otherwise */ public boolean isStarted() { - return Boolean.valueOf("Started"); + return Boolean.valueOf(getField("Started")); } + public boolean isTalkable() { + return Boolean.valueOf(getField("IsTalkable")); + } + + public String getVersion() { + return getField("Version"); + } + + public String getLongVersion() { + return getField("LongVersion"); + } } diff --git a/src/main/java/net/pterodactylus/fcp/PluginRemoved.java b/src/main/java/net/pterodactylus/fcp/PluginRemoved.java new file mode 100644 index 0000000..7492954 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/PluginRemoved.java @@ -0,0 +1,57 @@ +/* + * 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 “PluginRemoved” message is a reply to the {@link RemovePlugin} request. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + */ +public class PluginRemoved extends BaseMessage implements Identifiable { + + /** + * Creates a new “PluginRemoved” message that wraps the received message. + * + * @param receivedMessage + * The received message + */ + public PluginRemoved(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 + */ + @Override + public String getIdentifier() { + return getField("Identifier"); + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/ProtocolError.java b/src/main/java/net/pterodactylus/fcp/ProtocolError.java index 8b7b510..80d8487 100644 --- a/src/main/java/net/pterodactylus/fcp/ProtocolError.java +++ b/src/main/java/net/pterodactylus/fcp/ProtocolError.java @@ -31,7 +31,7 @@ public class ProtocolError extends BaseMessage { * @param receivedMessage * The received message */ - ProtocolError(FcpMessage receivedMessage) { + public ProtocolError(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/PutFailed.java b/src/main/java/net/pterodactylus/fcp/PutFailed.java index 8535bcb..7853d39 100644 --- a/src/main/java/net/pterodactylus/fcp/PutFailed.java +++ b/src/main/java/net/pterodactylus/fcp/PutFailed.java @@ -38,7 +38,7 @@ public class PutFailed extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - PutFailed(FcpMessage receivedMessage) { + public PutFailed(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/PutFetchable.java b/src/main/java/net/pterodactylus/fcp/PutFetchable.java index 767b4ad..c9867b0 100644 --- a/src/main/java/net/pterodactylus/fcp/PutFetchable.java +++ b/src/main/java/net/pterodactylus/fcp/PutFetchable.java @@ -33,7 +33,7 @@ public class PutFetchable extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - PutFetchable(FcpMessage receivedMessage) { + public PutFetchable(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/PutSuccessful.java b/src/main/java/net/pterodactylus/fcp/PutSuccessful.java index d8c4434..c5ee7fd 100644 --- a/src/main/java/net/pterodactylus/fcp/PutSuccessful.java +++ b/src/main/java/net/pterodactylus/fcp/PutSuccessful.java @@ -32,7 +32,7 @@ public class PutSuccessful extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - PutSuccessful(FcpMessage receivedMessage) { + public PutSuccessful(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/ReloadPlugin.java b/src/main/java/net/pterodactylus/fcp/ReloadPlugin.java new file mode 100644 index 0000000..bcdcde9 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/ReloadPlugin.java @@ -0,0 +1,31 @@ +package net.pterodactylus.fcp; + +/** + * The “ReloadPlugin” message is used to reload a plugin. + * + * @author David ‘Bombe’ Roden + */ +public class ReloadPlugin extends FcpMessage { + + public ReloadPlugin(String identifier) { + super("ReloadPlugin"); + setField("Identifier", identifier); + } + + public void setPluginName(String pluginName) { + setField("PluginName", pluginName); + } + + public void setMaxWaitTime(int maxWaitTime) { + setField("MaxWaitTime", String.valueOf(maxWaitTime)); + } + + public void setPurge(boolean purge) { + setField("Purge", String.valueOf(purge)); + } + + public void setStore(boolean store) { + setField("Store", String.valueOf(store)); + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/RemovePeer.java b/src/main/java/net/pterodactylus/fcp/RemovePeer.java index 5eae728..3f867fe 100644 --- a/src/main/java/net/pterodactylus/fcp/RemovePeer.java +++ b/src/main/java/net/pterodactylus/fcp/RemovePeer.java @@ -25,16 +25,15 @@ package net.pterodactylus.fcp; */ 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 - */ + @Deprecated public RemovePeer(String nodeIdentifier) { super("RemovePeer"); setField("NodeIdentifier", nodeIdentifier); } + public RemovePeer(String identifier, String nodeIdentifier) { + this(nodeIdentifier); + setField("Identifier", identifier); + } + } diff --git a/src/main/java/net/pterodactylus/fcp/RemovePlugin.java b/src/main/java/net/pterodactylus/fcp/RemovePlugin.java new file mode 100644 index 0000000..44fa9a7 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/RemovePlugin.java @@ -0,0 +1,27 @@ +package net.pterodactylus.fcp; + +/** + * The “RemovePlugin” message is used to remove a plugin. + * + * @author David ‘Bombe’ Roden + */ +public class RemovePlugin extends FcpMessage { + + public RemovePlugin(String identifier) { + super("RemovePlugin"); + setField("Identifier", identifier); + } + + public void setPluginName(String pluginName) { + setField("PluginName", pluginName); + } + + public void setMaxWaitTime(int maxWaitTime) { + setField("MaxWaitTime", String.valueOf(maxWaitTime)); + } + + public void setPurge(boolean purge) { + setField("Purge", String.valueOf(purge)); + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/RequestProgress.java b/src/main/java/net/pterodactylus/fcp/RequestProgress.java new file mode 100644 index 0000000..2dcc109 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/RequestProgress.java @@ -0,0 +1,63 @@ +package net.pterodactylus.fcp; + +/** + * Progress information about a request. + * + * @author David ‘Bombe’ Roden + */ +public class RequestProgress { + + private final int total; + private final int required; + private final int failed; + private final int fatallyFailed; + private final long lastProgress; + private final int succeeded; + private final boolean finalizedTotal; + private final int minSuccessFetchBlocks; + + public RequestProgress(int total, int required, int failed, int fatallyFailed, long lastProgress, int succeeded, + boolean finalizedTotal, int minSuccessFetchBlocks) { + this.total = total; + this.required = required; + this.failed = failed; + this.fatallyFailed = fatallyFailed; + this.lastProgress = lastProgress; + this.succeeded = succeeded; + this.finalizedTotal = finalizedTotal; + this.minSuccessFetchBlocks = minSuccessFetchBlocks; + } + + public int getTotal() { + return total; + } + + public int getRequired() { + return required; + } + + public int getFailed() { + return failed; + } + + public int getFatallyFailed() { + return fatallyFailed; + } + + public long getLastProgress() { + return lastProgress; + } + + public int getSucceeded() { + return succeeded; + } + + public boolean isFinalizedTotal() { + return finalizedTotal; + } + + public int getMinSuccessFetchBlocks() { + return minSuccessFetchBlocks; + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/SSKKeypair.java b/src/main/java/net/pterodactylus/fcp/SSKKeypair.java index 55b27e9..01a95f0 100644 --- a/src/main/java/net/pterodactylus/fcp/SSKKeypair.java +++ b/src/main/java/net/pterodactylus/fcp/SSKKeypair.java @@ -32,7 +32,7 @@ public class SSKKeypair extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - SSKKeypair(FcpMessage receivedMessage) { + public SSKKeypair(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/SimpleProgress.java b/src/main/java/net/pterodactylus/fcp/SimpleProgress.java index 5f4da24..69a3bf2 100644 --- a/src/main/java/net/pterodactylus/fcp/SimpleProgress.java +++ b/src/main/java/net/pterodactylus/fcp/SimpleProgress.java @@ -32,7 +32,7 @@ public class SimpleProgress extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - SimpleProgress(FcpMessage receivedMessage) { + public SimpleProgress(FcpMessage receivedMessage) { super(receivedMessage); } @@ -99,6 +99,14 @@ public class SimpleProgress extends BaseMessage implements Identifiable { return Boolean.valueOf(getField("FinalizedTotal")); } + public long getLastProgress() { + return Long.valueOf(getField("LastProgress")); + } + + public int getMinSuccessFetchBlocks() { + return Integer.valueOf(getField("MinSuccessFetchBlocks")); + } + /** * Returns the identifier of the request. * diff --git a/src/main/java/net/pterodactylus/fcp/StartedCompression.java b/src/main/java/net/pterodactylus/fcp/StartedCompression.java index 1fd44f1..3aac42c 100644 --- a/src/main/java/net/pterodactylus/fcp/StartedCompression.java +++ b/src/main/java/net/pterodactylus/fcp/StartedCompression.java @@ -33,7 +33,7 @@ public class StartedCompression extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - StartedCompression(FcpMessage receivedMessage) { + public StartedCompression(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/SubscribeUSK.java b/src/main/java/net/pterodactylus/fcp/SubscribeUSK.java index 6a18333..634d1de 100644 --- a/src/main/java/net/pterodactylus/fcp/SubscribeUSK.java +++ b/src/main/java/net/pterodactylus/fcp/SubscribeUSK.java @@ -24,22 +24,35 @@ package net.pterodactylus.fcp; * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> */ -public class SubscribeUSK extends FcpMessage { +public class SubscribeUSK extends FcpMessage implements Identifiable { - /** - * 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) { + public SubscribeUSK(String identifier) { super("SubscribeUSK"); - setField("URI", uri); setField("Identifier", identifier); } + public SubscribeUSK(String uri, String identifier) { + this(identifier); + setField("URI", uri); + } + + @Override + public String getIdentifier() { + return getField("Identifier"); + } + + public String getUri() { + return getField("URI"); + } + + public void setUri(String uri) { + setField("URI", uri); + } + + public boolean isActive() { + return !Boolean.parseBoolean(getField("DontPoll")); + } + /** * Sets whether updates for the USK are actively searched. * @@ -52,4 +65,52 @@ public class SubscribeUSK extends FcpMessage { setField("DontPoll", String.valueOf(!active)); } + public boolean isSparse() { + return Boolean.valueOf(getField("SparsePoll")); + } + + public void setSparse(boolean sparse) { + setField("SparsePoll", String.valueOf(sparse)); + } + + public Priority getPriority() { + String priorityClass = getField("PriorityClass"); + if (priorityClass != null) { + return Priority.valueOf(priorityClass); + } + return Priority.bulkSplitfile; + } + + public void setPriority(Priority priority) { + setField("PriorityClass", priority.toString()); + } + + public Priority getActivePriority() { + String priorityClass = getField("PriorityClassProgress"); + if (priorityClass != null) { + return Priority.valueOf(priorityClass); + } + return Priority.update; + } + + public void setActivePriority(Priority activePriority) { + setField("PriorityClassProgress", activePriority.toString()); + } + + public boolean isRealTime() { + return Boolean.valueOf(getField("RealTimeFlag")); + } + + public void setRealTime(boolean realTime) { + setField("RealTimeFlag", String.valueOf(realTime)); + } + + public boolean isIgnoreDateHints() { + return Boolean.valueOf(getField("IgnoreUSKDatehints")); + } + + public void setIgnoreDateHints(boolean ignoreDateHints) { + setField("IgnoreUSKDatehints", String.valueOf(ignoreDateHints)); + } + } diff --git a/src/main/java/net/pterodactylus/fcp/SubscribedUSK.java b/src/main/java/net/pterodactylus/fcp/SubscribedUSK.java new file mode 100644 index 0000000..f4c5d4d --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/SubscribedUSK.java @@ -0,0 +1,45 @@ +/* + * 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 “SubscribedUSK” message is sent when a {@link SubscribeUSK} was succesfully processed. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + */ +public class SubscribedUSK extends BaseMessage implements Identifiable { + + public SubscribedUSK(FcpMessage receivedMessage) { + super(receivedMessage); + } + + @Override + public String getIdentifier() { + return getField("Identifier"); + } + + public String getURI() { + return getField("URI"); + } + + public boolean isDontPoll() { + return Boolean.parseBoolean(getField("DontPoll")); + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/SubscribedUSKUpdate.java b/src/main/java/net/pterodactylus/fcp/SubscribedUSKUpdate.java index d2e132d..21cd466 100644 --- a/src/main/java/net/pterodactylus/fcp/SubscribedUSKUpdate.java +++ b/src/main/java/net/pterodactylus/fcp/SubscribedUSKUpdate.java @@ -36,7 +36,7 @@ public class SubscribedUSKUpdate extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - SubscribedUSKUpdate(FcpMessage receivedMessage) { + public SubscribedUSKUpdate(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/TestDDAComplete.java b/src/main/java/net/pterodactylus/fcp/TestDDAComplete.java index bea91d9..0a66de7 100644 --- a/src/main/java/net/pterodactylus/fcp/TestDDAComplete.java +++ b/src/main/java/net/pterodactylus/fcp/TestDDAComplete.java @@ -32,7 +32,7 @@ public class TestDDAComplete extends BaseMessage { * @param receivedMessage * The received message */ - TestDDAComplete(FcpMessage receivedMessage) { + public TestDDAComplete(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/TestDDAReply.java b/src/main/java/net/pterodactylus/fcp/TestDDAReply.java index 9764a02..9e2b6d4 100644 --- a/src/main/java/net/pterodactylus/fcp/TestDDAReply.java +++ b/src/main/java/net/pterodactylus/fcp/TestDDAReply.java @@ -36,7 +36,7 @@ public class TestDDAReply extends BaseMessage { * @param receivedMessage * The received message */ - TestDDAReply(FcpMessage receivedMessage) { + public TestDDAReply(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/TestDDAResponse.java b/src/main/java/net/pterodactylus/fcp/TestDDAResponse.java index 2d6d2a4..b508e04 100644 --- a/src/main/java/net/pterodactylus/fcp/TestDDAResponse.java +++ b/src/main/java/net/pterodactylus/fcp/TestDDAResponse.java @@ -56,6 +56,7 @@ public class TestDDAResponse extends FcpMessage { */ public TestDDAResponse(String directory, String readContent) { super("TestDDAResponse"); + setField("Directory", directory); if (readContent != null) { setField("ReadContent", readContent); } diff --git a/src/main/java/net/pterodactylus/fcp/URIGenerated.java b/src/main/java/net/pterodactylus/fcp/URIGenerated.java index 4939570..1b126f1 100644 --- a/src/main/java/net/pterodactylus/fcp/URIGenerated.java +++ b/src/main/java/net/pterodactylus/fcp/URIGenerated.java @@ -33,7 +33,7 @@ public class URIGenerated extends BaseMessage implements Identifiable { * @param receivedMessage * The received message */ - URIGenerated(FcpMessage receivedMessage) { + public URIGenerated(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/UnknownNodeIdentifier.java b/src/main/java/net/pterodactylus/fcp/UnknownNodeIdentifier.java index af7b2f5..a0d0891 100644 --- a/src/main/java/net/pterodactylus/fcp/UnknownNodeIdentifier.java +++ b/src/main/java/net/pterodactylus/fcp/UnknownNodeIdentifier.java @@ -33,7 +33,7 @@ public class UnknownNodeIdentifier extends BaseMessage { * @param receivedMessage * The received message */ - UnknownNodeIdentifier(FcpMessage receivedMessage) { + public UnknownNodeIdentifier(FcpMessage receivedMessage) { super(receivedMessage); } diff --git a/src/main/java/net/pterodactylus/fcp/UnsubscribeUSK.java b/src/main/java/net/pterodactylus/fcp/UnsubscribeUSK.java new file mode 100644 index 0000000..baadefb --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/UnsubscribeUSK.java @@ -0,0 +1,15 @@ +package net.pterodactylus.fcp; + +/** + * The “UnsubscribeUSK” message is used to cancel a {@link SubscribeUSK USK subscription}. + * + * @author David ‘Bombe’ Roden + */ +public class UnsubscribeUSK extends FcpMessage { + + public UnsubscribeUSK(String identifier) { + super("UnsubscribeUSK"); + setField("Identifier", identifier); + } + +} diff --git a/src/test/java/net/pterodactylus/fcp/ModifyPeerNoteTest.java b/src/test/java/net/pterodactylus/fcp/ModifyPeerNoteTest.java new file mode 100644 index 0000000..f82e012 --- /dev/null +++ b/src/test/java/net/pterodactylus/fcp/ModifyPeerNoteTest.java @@ -0,0 +1,28 @@ +package net.pterodactylus.fcp; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.junit.Test; + +/** + * Unit test for {@link ModifyPeerNote}. + * + * @author David ‘Bombe’ Roden + */ +public class ModifyPeerNoteTest { + + private static final String IDENTIFIER = "identifier"; + private static final String NODE_IDENTIFIER = "node_identifier"; + private static final String ENCODED_NOTE_TEXT = "VWJlck5vZGUgKHVudGlsIEkgaGF2ZSByZWFsIHBlZXJzKQ=="; + private static final String DECODED_NOTE_TEXT = "UberNode (until I have real peers)"; + + @Test + public void noteTextIsEncodedCorrectly() { + ModifyPeerNote modifyPeerNote = new ModifyPeerNote(IDENTIFIER, NODE_IDENTIFIER); + modifyPeerNote.setNoteText(DECODED_NOTE_TEXT); + assertThat(modifyPeerNote.getField("NoteText"), is(ENCODED_NOTE_TEXT)); + } + + +} diff --git a/src/test/java/net/pterodactylus/fcp/PeerNoteTest.java b/src/test/java/net/pterodactylus/fcp/PeerNoteTest.java new file mode 100644 index 0000000..ce73f4c --- /dev/null +++ b/src/test/java/net/pterodactylus/fcp/PeerNoteTest.java @@ -0,0 +1,23 @@ +package net.pterodactylus.fcp; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.junit.Test; + +/** + * Unit test for {@link PeerNote}. + * + * @author David ‘Bombe’ Roden + */ +public class PeerNoteTest { + + @Test + public void peerNoteIsDecodedCorrectly() { + FcpMessage receivedMessage = new FcpMessage("PeerNote"); + receivedMessage.setField("NoteText", "VWJlck5vZGUgKHVudGlsIEkgaGF2ZSByZWFsIHBlZXJzKQ=="); + PeerNote peerNote = new PeerNote(receivedMessage); + assertThat(peerNote.getNoteText(), is("UberNode (until I have real peers)")); + } + +}