/*
- * todesbaum-lib -
+ * todesbaum-lib -
* Copyright (C) 2006 David Roden
*
* This program is free software; you can redistribute it and/or modify
package de.todesbaum.util.freenet.fcp2;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.SequenceInputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
-import java.util.Vector;
+
+import de.todesbaum.util.io.Closer;
/**
- * Implementation of the <code>ClientPutComplexDir</code> command. This
- * command can be used to insert directories that do not exist on disk.
- *
+ * Implementation of the <code>ClientPutComplexDir</code> command. This command
+ * can be used to insert directories that do not exist on disk.
+ *
* @author David Roden <droden@gmail.com>
- * @version $Id: ClientPutComplexDir.java 356 2006-03-24 15:13:38Z bombe $
+ * @version $Id$
*/
-public class ClientPutComplexDir extends ClientPutDir {
+public class ClientPutComplexDir extends ClientPutDir<ClientPutComplexDir> {
/** The file entries of this directory. */
private List<FileEntry> fileEntries = new ArrayList<FileEntry>();
-
+
/** Whether this request has payload. */
private boolean hasPayload = false;
-
+
/** The input streams for the payload. */
- private List<InputStream> payloadInputStreams = new ArrayList<InputStream>();
-
+ private File payloadFile;
+
/** The total number of bytes of the payload. */
private long payloadLength = 0;
+ /** The temp directory to use. */
+ private final String tempDirectory;
+
/**
- * Creates a new <code>ClientPutComplexDir</code> command with the specified identifier and URI.
- * @param identifier The identifier of the command
- * @param uri The URI of the command
+ * Creates a new <code>ClientPutComplexDir</code> command with the specified
+ * identifier and URI.
+ *
+ * @param identifier
+ * The identifier of the command
+ * @param uri
+ * The URI of the command
*/
public ClientPutComplexDir(String identifier, String uri) {
+ this(identifier, uri, null);
+ }
+
+ /**
+ * Creates a new <code>ClientPutComplexDir</code> command with the specified
+ * identifier and URI.
+ *
+ * @param identifier
+ * The identifier of the command
+ * @param uri
+ * The URI of the command
+ * @param tempDirectory
+ * The temp directory to use, or {@code null} to use the default
+ * temp directory
+ */
+ public ClientPutComplexDir(String identifier, String uri, String tempDirectory) {
super("ClientPutComplexDir", identifier, uri);
+ this.tempDirectory = tempDirectory;
}
/**
* Adds a file to the directory inserted by this request.
- * @param fileEntry The file entry to add to the directory
+ *
+ * @param fileEntry
+ * The file entry to add to the directory
+ * @throws IOException
+ * if an I/O error occurs when creating the payload stream
*/
- public void addFileEntry(FileEntry fileEntry) {
- fileEntries.add(fileEntry);
+ public void addFileEntry(FileEntry fileEntry) throws IOException {
+ if (fileEntry instanceof DirectFileEntry) {
+ if (payloadFile == null) {
+ try {
+ payloadFile = File.createTempFile("payload", ".dat", (tempDirectory != null) ? new File(tempDirectory) : null);
+ payloadFile.deleteOnExit();
+ } catch (IOException e) {
+ /* ignore. */
+ }
+ }
+ if (payloadFile != null) {
+ InputStream payloadInputStream = ((DirectFileEntry) fileEntry).getDataInputStream();
+ FileOutputStream payloadOutputStream = null;
+ try {
+ payloadOutputStream = new FileOutputStream(payloadFile, true);
+ byte[] buffer = new byte[65536];
+ int read = 0;
+ while ((read = payloadInputStream.read(buffer)) != -1) {
+ payloadOutputStream.write(buffer, 0, read);
+ }
+ payloadOutputStream.flush();
+ fileEntries.add(fileEntry);
+ } catch (IOException ioe1) {
+ payloadFile.delete();
+ throw ioe1;
+ } finally {
+ Closer.close(payloadOutputStream);
+ Closer.close(payloadInputStream);
+ }
+ }
+ } else {
+ fileEntries.add(fileEntry);
+ }
}
/**
protected void write(Writer writer) throws IOException {
super.write(writer);
int fileIndex = 0;
- for (FileEntry fileEntry: fileEntries) {
+ for (FileEntry fileEntry : fileEntries) {
writer.write("Files." + fileIndex + ".Name=" + fileEntry.getFilename() + LINEFEED);
if (fileEntry.getContentType() != null) {
writer.write("Files." + fileIndex + ".Metadata.ContentType=" + fileEntry.getContentType() + LINEFEED);
hasPayload = true;
writer.write("Files." + fileIndex + ".DataLength=" + ((DirectFileEntry) fileEntry).getDataLength() + LINEFEED);
payloadLength += ((DirectFileEntry) fileEntry).getDataLength();
- payloadInputStreams.add(((DirectFileEntry) fileEntry).getDataInputStream());
} else if (fileEntry instanceof DiskFileEntry) {
writer.write("Files." + fileIndex + ".Filename=" + ((DiskFileEntry) fileEntry).getFilename() + LINEFEED);
} else if (fileEntry instanceof RedirectFileEntry) {
*/
@Override
protected InputStream getPayload() {
- /* grr. use Vector here because it returns an Enumeration. */
- Vector<InputStream> inputStreams = new Vector<InputStream>(payloadInputStreams);
- return new SequenceInputStream(inputStreams.elements());
+ if (payloadFile != null) {
+ try {
+ return new FileInputStream(payloadFile);
+ } catch (FileNotFoundException e) {
+ /* shouldn't occur. */
+ }
+ }
+ return null;
}
}