From e7a6fcccea05f3866863b7678bf114b3de2b3192 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 12 Apr 2008 20:14:36 +0000 Subject: [PATCH] add ClientPutComplexDir git-svn-id: http://trooper/svn/projects/jSite/trunk@738 c3eda9e8-030b-0410-8277-bc7414b0a119 --- TODO | 1 - .../util/fcp/ClientPutComplexDir.java | 222 +++++++++++++++ src/net/pterodactylus/util/fcp/FileEntry.java | 299 +++++++++++++++++++++ 3 files changed, 521 insertions(+), 1 deletion(-) create mode 100644 src/net/pterodactylus/util/fcp/ClientPutComplexDir.java create mode 100644 src/net/pterodactylus/util/fcp/FileEntry.java diff --git a/TODO b/TODO index 38908d0..8c49a63 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,3 @@ -ClientPutComplexDir ClientPutDiskDir GetPluginInfo (since 1075) GetRequestStatus diff --git a/src/net/pterodactylus/util/fcp/ClientPutComplexDir.java b/src/net/pterodactylus/util/fcp/ClientPutComplexDir.java new file mode 100644 index 0000000..a2d541e --- /dev/null +++ b/src/net/pterodactylus/util/fcp/ClientPutComplexDir.java @@ -0,0 +1,222 @@ +/* + * jSite2 - ClientPutComplexDir.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.util.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.util.fcp.FileEntry.DirectFileEntry; + +/** + * The “ClientPutComplexDir” lets you upload a directory with different sources + * for each file. + * + * @see FileEntry + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class ClientPutComplexDir extends FcpMessage { + + /** The index for added file entries. */ + private int fileIndex = 0; + + /** The input streams from {@link DirectFileEntry}s. */ + private final List directFileInputStreams = new ArrayList(); + + /** + * Creates a new “ClientPutComplexDir” with the given identifier and URI. + * + * @param identifier + * The identifier of the request + * @param uri + * The URI to insert the directory to + */ + public ClientPutComplexDir(String identifier, String uri) { + super("ClientPutComplexDir"); + setField("Identifier", identifier); + setField("URI", uri); + } + + /** + * Sets the verbosity of the request. + * + * @param verbosity + * The verbosity of the request + */ + public void setVerbosity(Verbosity verbosity) { + setField("Verbosity", String.valueOf(verbosity)); + } + + /** + * Sets the maximum number of retries for failed blocks. + * + * @param maxRetries + * The maximum number of retries for failed blocks, or + * -1 to retry endlessly + */ + public void setMaxRetries(int maxRetries) { + setField("MaxRetries", String.valueOf(maxRetries)); + } + + /** + * Sets the priority of the request. + * + * @param priority + * The priority of the request + */ + public void setPriority(Priority priority) { + setField("PriorityClass", String.valueOf(priority)); + } + + /** + * Sets whether to generate the final URI only. + * + * @param getCHKOnly + * true to generate the final CHK only, + * false to complete the insert + */ + public void setGetCHKOnly(boolean getCHKOnly) { + setField("GetCHKOnly", String.valueOf(getCHKOnly)); + } + + /** + * Sets whether the request is on the global queue. + * + * @param global + * true to put the request on the global queue, + * false to put it on the client-local queue + */ + public void setGlobal(boolean global) { + setField("Global", String.valueOf(global)); + } + + /** + * Sets whether the node should not try to compress the data. + * + * @param dontCompress + * true to skip compression of the data, + * false to try and compress the data + */ + public void setDontCompress(boolean dontCompress) { + setField("DontCompress", String.valueOf(dontCompress)); + } + + /** + * Sets the client token of the request. + * + * @param clientToken + * The client token of the request + */ + public void setClientToken(String clientToken) { + setField("ClientToken", clientToken); + } + + /** + * Sets the persistence of the request. + * + * @param persistence + * The persistence of the request + */ + public void setPersistence(Persistence persistence) { + setField("Persistence", String.valueOf(persistence)); + } + + /** + * Sets the target filename of the request. This is useful for inserts that + * go to “CHK@” only and creates a manifest with a single file. + * + * @param targetFilename + * The target filename + */ + public void setTargetFilename(String targetFilename) { + setField("TargetFilename", targetFilename); + } + + /** + * Sets whether to encode the complete data early to generate the + * {@link URIGenerated} message early. + * + * @param earlyEncode + * true to encode the complete data early, + * false otherwise + */ + public void setEarlyEncode(boolean earlyEncode) { + setField("EarlyEncode", String.valueOf(earlyEncode)); + } + + /** + * Sets the default name. This is the name of the file that should be shown + * if no file was specified. + * + * @param defaultName + * The default name + */ + public void setDefaultName(String defaultName) { + setField("DefaultName", defaultName); + } + + /** + * Adds an entry for a file. + * + * @param fileEntry + * The file entry to add + */ + public void addFileEntry(FileEntry fileEntry) { + Map fields = fileEntry.getFields(); + for (Entry fieldEntry: fields.entrySet()) { + setField("Files." + fileIndex + "." + fieldEntry.getKey(), fieldEntry.getValue()); + } + fileIndex++; + if (fileEntry instanceof FileEntry.DirectFileEntry) { + directFileInputStreams.add(((DirectFileEntry) fileEntry).getInputStream()); + } + } + + /** + * {@inheritDoc} + *

+ * Do not call this method to add input streams! The input streams, if any, + * will be taken directly from the {@link FileEntry}s and the stream you + * set here will be overridden! + */ + @Override + public void setPayloadInputStream(InputStream payloadInputStream) { + /* do nothing. */ + } + + /** + * {@inheritDoc} + */ + @Override + public void write(OutputStream outputStream) throws IOException { + /* create payload stream. */ + setPayloadInputStream(new SequenceInputStream(Collections.enumeration(directFileInputStreams))); + /* write out all the fields. */ + super.write(outputStream); + } + +} diff --git a/src/net/pterodactylus/util/fcp/FileEntry.java b/src/net/pterodactylus/util/fcp/FileEntry.java new file mode 100644 index 0000000..d227a34 --- /dev/null +++ b/src/net/pterodactylus/util/fcp/FileEntry.java @@ -0,0 +1,299 @@ +/* + * jSite2 - FileEntry.java - + * Copyright © 2008 David Roden + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package net.pterodactylus.util.fcp; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * Container class for file entry data. + * + * @see ClientPutComplexDir#addFileEntry(FileEntry) + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public abstract class FileEntry { + + /** The name of the file. */ + protected final String name; + + /** The upload source of the file. */ + protected final UploadFrom uploadFrom; + + /** + * Creates a new file entry with the given name and upload source. + * + * @param name + * The name of the file + * @param uploadFrom + * The upload source of the file + */ + protected FileEntry(String name, UploadFrom uploadFrom) { + this.name = name; + this.uploadFrom = uploadFrom; + } + + /** + * Creates a new file entry for a file that should be transmitted to the + * node in the payload of the message. + * + * @param name + * The name of the file + * @param contentType + * The content type of the file, or null to let + * the node auto-detect it + * @param length + * The length of the file + * @param dataInputStream + * The input stream of the file + * @return A file entry + */ + public static FileEntry createDirectFileEntry(String name, String contentType, long length, InputStream dataInputStream) { + return new DirectFileEntry(name, contentType, length, dataInputStream); + } + + /** + * Creates a new file entry for a file that should be uploaded from disk. + * + * @param name + * The name of the file + * @param filename + * The name of the file on disk + * @param contentType + * The content type of the file, or null to let + * the node auto-detect it + * @param length + * The length of the file, or -1 to not specify a + * size + * @return A file entry + */ + public static FileEntry createDiskFileEntry(String name, String filename, String contentType, long length) { + return new DiskFileEntry(name, filename, contentType, length); + } + + /** + * Creates a new file entry for a file that redirects to another URI. + * + * @param name + * The name of the file + * @param targetURI + * The target URI of the redirect + * @return A file entry + */ + public static FileEntry createRedirectFileEntry(String name, String targetURI) { + return new RedirectFileEntry(name, targetURI); + } + + /** + * Returns the fields for this file entry. + * + * @return The fields for this file entry + */ + abstract Map getFields(); + + /** + * A file entry for a file that should be transmitted in the payload of the + * {@link ClientPutComplexDir} message. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ + static class DirectFileEntry extends FileEntry { + + /** The content type of the data. */ + private final String contentType; + + /** The length of the data. */ + private final long length; + + /** The input stream of the data. */ + private final InputStream inputStream; + + /** + * Creates a new direct file entry with content type auto-detection. + * + * @param name + * The name of the file + * @param length + * The length of the file + * @param inputStream + * The input stream of the file + */ + public DirectFileEntry(String name, long length, InputStream inputStream) { + this(name, null, length, inputStream); + } + + /** + * Creates a new direct file entry. + * + * @param name + * The name of the file + * @param contentType + * The content type of the file, or null to + * let the node auto-detect it + * @param length + * The length of the file + * @param inputStream + * The input stream of the file + */ + public DirectFileEntry(String name, String contentType, long length, InputStream inputStream) { + super(name, UploadFrom.direct); + this.contentType = contentType; + this.length = length; + this.inputStream = inputStream; + } + + /** + * {@inheritDoc} + */ + @Override + Map getFields() { + Map fields = new HashMap(); + fields.put("Name", name); + fields.put("UploadFrom", String.valueOf(uploadFrom)); + fields.put("DataLength", String.valueOf(length)); + if (contentType != null) { + fields.put("Metadata.ContentType", contentType); + } + return fields; + } + + /** + * Returns the input stream of the file. + * + * @return The input stream of the file + */ + InputStream getInputStream() { + return inputStream; + } + + } + + /** + * A file entry for a file that should be uploaded from the disk. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ + static class DiskFileEntry extends FileEntry { + + /** The name of the on-disk file. */ + private final String filename; + + /** The content type of the file. */ + private final String contentType; + + /** The length of the file. */ + private final long length; + + /** + * Creates a new disk file entry. + * + * @param name + * The name of the file + * @param filename + * The name of the on-disk file + * @param length + * The length of the file + */ + public DiskFileEntry(String name, String filename, long length) { + this(name, filename, null, length); + } + + /** + * Creates a new disk file entry. + * + * @param name + * The name of the file + * @param filename + * The name of the on-disk file + * @param contentType + * The content type of the file, or null to + * let the node auto-detect it + * @param length + * The length of the file + */ + public DiskFileEntry(String name, String filename, String contentType, long length) { + super(name, UploadFrom.disk); + this.filename = filename; + this.contentType = contentType; + this.length = length; + } + + /** + * {@inheritDoc} + */ + @Override + Map getFields() { + Map fields = new HashMap(); + fields.put("Name", name); + fields.put("UploadFrom", String.valueOf(uploadFrom)); + fields.put("Filename", filename); + if (length > -1) { + fields.put("DataSize", String.valueOf(length)); + } + if (contentType != null) { + fields.put("Metadata.ContentType", contentType); + } + return fields; + } + + } + + /** + * A file entry for a file that redirects to another URI. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ + static class RedirectFileEntry extends FileEntry { + + /** The target URI of the redirect. */ + private String targetURI; + + /** + * Creates a new redirect file entry. + * + * @param name + * The name of the file + * @param targetURI + * The target URI of the redirect + */ + public RedirectFileEntry(String name, String targetURI) { + super(name, UploadFrom.redirect); + this.targetURI = targetURI; + } + + /** + * {@inheritDoc} + */ + @Override + Map getFields() { + Map fields = new HashMap(); + fields.put("Name", name); + fields.put("UploadFrom", String.valueOf(uploadFrom)); + fields.put("TargetURI", targetURI); + return fields; + } + + } + +} -- 2.7.4