|
|
@ -16,33 +16,28 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
package com.fr.third.org.apache.commons.fileupload.disk; |
|
|
|
package com.fr.third.org.apache.commons.fileupload.disk; |
|
|
|
|
|
|
|
|
|
|
|
import static java.lang.String.format; |
|
|
|
import com.fr.third.org.apache.commons.fileupload.FileItem; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.fileupload.FileItemHeaders; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.fileupload.FileUploadException; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.fileupload.ParameterParser; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.fileupload.util.Streams; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.io.FileUtils; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.io.IOUtils; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.io.output.DeferredFileOutputStream; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.BufferedInputStream; |
|
|
|
|
|
|
|
import java.io.BufferedOutputStream; |
|
|
|
|
|
|
|
import java.io.ByteArrayInputStream; |
|
|
|
import java.io.ByteArrayInputStream; |
|
|
|
import java.io.File; |
|
|
|
import java.io.File; |
|
|
|
import java.io.FileInputStream; |
|
|
|
import java.io.FileInputStream; |
|
|
|
import java.io.FileOutputStream; |
|
|
|
import java.io.FileOutputStream; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.io.ObjectInputStream; |
|
|
|
|
|
|
|
import java.io.ObjectOutputStream; |
|
|
|
|
|
|
|
import java.io.OutputStream; |
|
|
|
import java.io.OutputStream; |
|
|
|
import java.io.UnsupportedEncodingException; |
|
|
|
import java.io.UnsupportedEncodingException; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.UUID; |
|
|
|
import java.util.UUID; |
|
|
|
import java.util.concurrent.atomic.AtomicInteger; |
|
|
|
import java.util.concurrent.atomic.AtomicInteger; |
|
|
|
|
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.fileupload.FileItem; |
|
|
|
import static java.lang.String.format; |
|
|
|
import com.fr.third.org.apache.commons.fileupload.FileItemHeaders; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.fileupload.FileUploadException; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.fileupload.InvalidFileNameException; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.fileupload.ParameterParser; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.fileupload.util.Streams; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.io.IOUtils; |
|
|
|
|
|
|
|
import com.fr.third.org.apache.commons.io.output.DeferredFileOutputStream; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* <p> The default implementation of the |
|
|
|
* <p> The default implementation of the |
|
|
@ -50,47 +45,34 @@ import com.fr.third.org.apache.commons.io.output.DeferredFileOutputStream; |
|
|
|
* |
|
|
|
* |
|
|
|
* <p> After retrieving an instance of this class from a {@link |
|
|
|
* <p> After retrieving an instance of this class from a {@link |
|
|
|
* DiskFileItemFactory} instance (see |
|
|
|
* DiskFileItemFactory} instance (see |
|
|
|
* {@link ServletFileUpload |
|
|
|
* {@link com.fr.third.org.apache.commons.fileupload.servlet.ServletFileUpload |
|
|
|
* #parseRequest(javax.servlet.http.HttpServletRequest)}), you may |
|
|
|
* #parseRequest(javax.servlet.http.HttpServletRequest)}), you may |
|
|
|
* either request all contents of file at once using {@link #get()} or |
|
|
|
* either request all contents of file at once using {@link #get()} or |
|
|
|
* request an {@link java.io.InputStream InputStream} with |
|
|
|
* request an {@link InputStream InputStream} with |
|
|
|
* {@link #getInputStream()} and process the file without attempting to load |
|
|
|
* {@link #getInputStream()} and process the file without attempting to load |
|
|
|
* it into memory, which may come handy with large files. |
|
|
|
* it into memory, which may come handy with large files. |
|
|
|
* |
|
|
|
* |
|
|
|
* <p>Temporary files, which are created for file items, should be |
|
|
|
* <p>Temporary files, which are created for file items, should be |
|
|
|
* deleted later on. The best way to do this is using a |
|
|
|
* deleted later on. The best way to do this is using a |
|
|
|
* {@link org.apache.commons.io.FileCleaningTracker}, which you can set on the |
|
|
|
* {@link com.fr.third.org.apache.commons.io.FileCleaningTracker}, which you can set on the |
|
|
|
* {@link DiskFileItemFactory}. However, if you do use such a tracker, |
|
|
|
* {@link DiskFileItemFactory}. However, if you do use such a tracker, |
|
|
|
* then you must consider the following: Temporary files are automatically |
|
|
|
* then you must consider the following: Temporary files are automatically |
|
|
|
* deleted as soon as they are no longer needed. (More precisely, when the |
|
|
|
* deleted as soon as they are no longer needed. (More precisely, when the |
|
|
|
* corresponding instance of {@link java.io.File} is garbage collected.) |
|
|
|
* corresponding instance of {@link File} is garbage collected.) |
|
|
|
* This is done by the so-called reaper thread, which is started and stopped |
|
|
|
* This is done by the so-called reaper thread, which is started and stopped |
|
|
|
* automatically by the {@link org.apache.commons.io.FileCleaningTracker} when |
|
|
|
* automatically by the {@link com.fr.third.org.apache.commons.io.FileCleaningTracker} when |
|
|
|
* there are files to be tracked. |
|
|
|
* there are files to be tracked. |
|
|
|
* It might make sense to terminate that thread, for example, if |
|
|
|
* It might make sense to terminate that thread, for example, if |
|
|
|
* your web application ends. See the section on "Resource cleanup" |
|
|
|
* your web application ends. See the section on "Resource cleanup" |
|
|
|
* in the users guide of commons-fileupload.</p> |
|
|
|
* in the users guide of commons-fileupload.</p> |
|
|
|
* |
|
|
|
* |
|
|
|
* @since FileUpload 1.1 |
|
|
|
* @since FileUpload 1.1 |
|
|
|
* |
|
|
|
|
|
|
|
* @version $Id$ |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class DiskFileItem |
|
|
|
public class DiskFileItem |
|
|
|
implements FileItem { |
|
|
|
implements FileItem { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Although it implements {@link java.io.Serializable}, a DiskFileItem can actually only be deserialized, |
|
|
|
|
|
|
|
* if this System property is true. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public static final String SERIALIZABLE_PROPERTY = DiskFileItem.class.getName() + ".serializable"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------- Manifest constants
|
|
|
|
// ----------------------------------------------------- Manifest constants
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* The UID to use when serializing this instance. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private static final long serialVersionUID = 2237570099615271025L; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Default content charset to be used when no explicit charset |
|
|
|
* Default content charset to be used when no explicit charset |
|
|
|
* parameter is provided by the sender. Media subtypes of the |
|
|
|
* parameter is provided by the sender. Media subtypes of the |
|
|
@ -166,14 +148,15 @@ public class DiskFileItem |
|
|
|
private transient File tempFile; |
|
|
|
private transient File tempFile; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* File to allow for serialization of the content of this item. |
|
|
|
* The file items headers. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private File dfosFile; |
|
|
|
private FileItemHeaders headers; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The file items headers. |
|
|
|
* Default content charset to be used when no explicit charset |
|
|
|
|
|
|
|
* parameter is provided by the sender. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private FileItemHeaders headers; |
|
|
|
private String defaultCharset = DEFAULT_CHARSET; |
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------- Constructors
|
|
|
|
// ----------------------------------------------------------- Constructors
|
|
|
|
|
|
|
|
|
|
|
@ -208,14 +191,15 @@ public class DiskFileItem |
|
|
|
// ------------------------------- Methods from javax.activation.DataSource
|
|
|
|
// ------------------------------- Methods from javax.activation.DataSource
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Returns an {@link java.io.InputStream InputStream} that can be |
|
|
|
* Returns an {@link InputStream InputStream} that can be |
|
|
|
* used to retrieve the contents of the file. |
|
|
|
* used to retrieve the contents of the file. |
|
|
|
* |
|
|
|
* |
|
|
|
* @return An {@link java.io.InputStream InputStream} that can be |
|
|
|
* @return An {@link InputStream InputStream} that can be |
|
|
|
* used to retrieve the contents of the file. |
|
|
|
* used to retrieve the contents of the file. |
|
|
|
* |
|
|
|
* |
|
|
|
* @throws IOException if an error occurs. |
|
|
|
* @throws IOException if an error occurs. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public InputStream getInputStream() |
|
|
|
public InputStream getInputStream() |
|
|
|
throws IOException { |
|
|
|
throws IOException { |
|
|
|
if (!isInMemory()) { |
|
|
|
if (!isInMemory()) { |
|
|
@ -235,6 +219,7 @@ public class DiskFileItem |
|
|
|
* @return The content type passed by the agent or <code>null</code> if |
|
|
|
* @return The content type passed by the agent or <code>null</code> if |
|
|
|
* not defined. |
|
|
|
* not defined. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public String getContentType() { |
|
|
|
public String getContentType() { |
|
|
|
return contentType; |
|
|
|
return contentType; |
|
|
|
} |
|
|
|
} |
|
|
@ -258,11 +243,12 @@ public class DiskFileItem |
|
|
|
* Returns the original filename in the client's filesystem. |
|
|
|
* Returns the original filename in the client's filesystem. |
|
|
|
* |
|
|
|
* |
|
|
|
* @return The original filename in the client's filesystem. |
|
|
|
* @return The original filename in the client's filesystem. |
|
|
|
* @throws InvalidFileNameException The file name contains a NUL character, |
|
|
|
* @throws com.fr.third.org.apache.commons.fileupload.InvalidFileNameException The file name contains a NUL character, |
|
|
|
* which might be an indicator of a security attack. If you intend to |
|
|
|
* which might be an indicator of a security attack. If you intend to |
|
|
|
* use the file name anyways, catch the exception and use |
|
|
|
* use the file name anyways, catch the exception and use |
|
|
|
* {@link InvalidFileNameException#getName()}. |
|
|
|
* {@link com.fr.third.org.apache.commons.fileupload.InvalidFileNameException#getName()}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public String getName() { |
|
|
|
public String getName() { |
|
|
|
return Streams.checkFileName(fileName); |
|
|
|
return Streams.checkFileName(fileName); |
|
|
|
} |
|
|
|
} |
|
|
@ -276,6 +262,7 @@ public class DiskFileItem |
|
|
|
* @return <code>true</code> if the file contents will be read |
|
|
|
* @return <code>true</code> if the file contents will be read |
|
|
|
* from memory; <code>false</code> otherwise. |
|
|
|
* from memory; <code>false</code> otherwise. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public boolean isInMemory() { |
|
|
|
public boolean isInMemory() { |
|
|
|
if (cachedContent != null) { |
|
|
|
if (cachedContent != null) { |
|
|
|
return true; |
|
|
|
return true; |
|
|
@ -288,6 +275,7 @@ public class DiskFileItem |
|
|
|
* |
|
|
|
* |
|
|
|
* @return The size of the file, in bytes. |
|
|
|
* @return The size of the file, in bytes. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public long getSize() { |
|
|
|
public long getSize() { |
|
|
|
if (size >= 0) { |
|
|
|
if (size >= 0) { |
|
|
|
return size; |
|
|
|
return size; |
|
|
@ -305,11 +293,13 @@ public class DiskFileItem |
|
|
|
* contents of the file were not yet cached in memory, they will be |
|
|
|
* contents of the file were not yet cached in memory, they will be |
|
|
|
* loaded from the disk storage and cached. |
|
|
|
* loaded from the disk storage and cached. |
|
|
|
* |
|
|
|
* |
|
|
|
* @return The contents of the file as an array of bytes. |
|
|
|
* @return The contents of the file as an array of bytes |
|
|
|
|
|
|
|
* or {@code null} if the data cannot be read |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public byte[] get() { |
|
|
|
public byte[] get() { |
|
|
|
if (isInMemory()) { |
|
|
|
if (isInMemory()) { |
|
|
|
if (cachedContent == null) { |
|
|
|
if (cachedContent == null && dfos != null) { |
|
|
|
cachedContent = dfos.getData(); |
|
|
|
cachedContent = dfos.getData(); |
|
|
|
} |
|
|
|
} |
|
|
|
return cachedContent; |
|
|
|
return cachedContent; |
|
|
@ -319,18 +309,12 @@ public class DiskFileItem |
|
|
|
InputStream fis = null; |
|
|
|
InputStream fis = null; |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
fis = new BufferedInputStream(new FileInputStream(dfos.getFile())); |
|
|
|
fis = new FileInputStream(dfos.getFile()); |
|
|
|
fis.read(fileData); |
|
|
|
IOUtils.readFully(fis, fileData); |
|
|
|
} catch (IOException e) { |
|
|
|
} catch (IOException e) { |
|
|
|
fileData = null; |
|
|
|
fileData = null; |
|
|
|
} finally { |
|
|
|
} finally { |
|
|
|
if (fis != null) { |
|
|
|
IOUtils.closeQuietly(fis); |
|
|
|
try { |
|
|
|
|
|
|
|
fis.close(); |
|
|
|
|
|
|
|
} catch (IOException e) { |
|
|
|
|
|
|
|
// ignore
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return fileData; |
|
|
|
return fileData; |
|
|
@ -348,6 +332,7 @@ public class DiskFileItem |
|
|
|
* @throws UnsupportedEncodingException if the requested character |
|
|
|
* @throws UnsupportedEncodingException if the requested character |
|
|
|
* encoding is not available. |
|
|
|
* encoding is not available. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public String getString(final String charset) |
|
|
|
public String getString(final String charset) |
|
|
|
throws UnsupportedEncodingException { |
|
|
|
throws UnsupportedEncodingException { |
|
|
|
return new String(get(), charset); |
|
|
|
return new String(get(), charset); |
|
|
@ -362,11 +347,12 @@ public class DiskFileItem |
|
|
|
* |
|
|
|
* |
|
|
|
* @return The contents of the file, as a string. |
|
|
|
* @return The contents of the file, as a string. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public String getString() { |
|
|
|
public String getString() { |
|
|
|
byte[] rawdata = get(); |
|
|
|
byte[] rawdata = get(); |
|
|
|
String charset = getCharSet(); |
|
|
|
String charset = getCharSet(); |
|
|
|
if (charset == null) { |
|
|
|
if (charset == null) { |
|
|
|
charset = DEFAULT_CHARSET; |
|
|
|
charset = defaultCharset; |
|
|
|
} |
|
|
|
} |
|
|
|
try { |
|
|
|
try { |
|
|
|
return new String(rawdata, charset); |
|
|
|
return new String(rawdata, charset); |
|
|
@ -395,16 +381,16 @@ public class DiskFileItem |
|
|
|
* |
|
|
|
* |
|
|
|
* @throws Exception if an error occurs. |
|
|
|
* @throws Exception if an error occurs. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public void write(File file) throws Exception { |
|
|
|
public void write(File file) throws Exception { |
|
|
|
if (isInMemory()) { |
|
|
|
if (isInMemory()) { |
|
|
|
FileOutputStream fout = null; |
|
|
|
FileOutputStream fout = null; |
|
|
|
try { |
|
|
|
try { |
|
|
|
fout = new FileOutputStream(file); |
|
|
|
fout = new FileOutputStream(file); |
|
|
|
fout.write(get()); |
|
|
|
fout.write(get()); |
|
|
|
|
|
|
|
fout.close(); |
|
|
|
} finally { |
|
|
|
} finally { |
|
|
|
if (fout != null) { |
|
|
|
IOUtils.closeQuietly(fout); |
|
|
|
fout.close(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
File outputFile = getStoreLocation(); |
|
|
|
File outputFile = getStoreLocation(); |
|
|
@ -416,32 +402,10 @@ public class DiskFileItem |
|
|
|
* in a temporary location so move it to the |
|
|
|
* in a temporary location so move it to the |
|
|
|
* desired file. |
|
|
|
* desired file. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
if (!outputFile.renameTo(file)) { |
|
|
|
if (file.exists()) { |
|
|
|
BufferedInputStream in = null; |
|
|
|
file.delete(); |
|
|
|
BufferedOutputStream out = null; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
in = new BufferedInputStream( |
|
|
|
|
|
|
|
new FileInputStream(outputFile)); |
|
|
|
|
|
|
|
out = new BufferedOutputStream( |
|
|
|
|
|
|
|
new FileOutputStream(file)); |
|
|
|
|
|
|
|
IOUtils.copy(in, out); |
|
|
|
|
|
|
|
} finally { |
|
|
|
|
|
|
|
if (in != null) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
in.close(); |
|
|
|
|
|
|
|
} catch (IOException e) { |
|
|
|
|
|
|
|
// ignore
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (out != null) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
out.close(); |
|
|
|
|
|
|
|
} catch (IOException e) { |
|
|
|
|
|
|
|
// ignore
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
FileUtils.moveFile(outputFile, file); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
/* |
|
|
|
/* |
|
|
|
* For whatever reason we cannot write the |
|
|
|
* For whatever reason we cannot write the |
|
|
@ -460,10 +424,11 @@ public class DiskFileItem |
|
|
|
* collected, this method can be used to ensure that this is done at an |
|
|
|
* collected, this method can be used to ensure that this is done at an |
|
|
|
* earlier time, thus preserving system resources. |
|
|
|
* earlier time, thus preserving system resources. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public void delete() { |
|
|
|
public void delete() { |
|
|
|
cachedContent = null; |
|
|
|
cachedContent = null; |
|
|
|
File outputFile = getStoreLocation(); |
|
|
|
File outputFile = getStoreLocation(); |
|
|
|
if (outputFile != null && outputFile.exists()) { |
|
|
|
if (outputFile != null && !isInMemory() && outputFile.exists()) { |
|
|
|
outputFile.delete(); |
|
|
|
outputFile.delete(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -474,9 +439,10 @@ public class DiskFileItem |
|
|
|
* |
|
|
|
* |
|
|
|
* @return The name of the form field. |
|
|
|
* @return The name of the form field. |
|
|
|
* |
|
|
|
* |
|
|
|
* @see #setFieldName(java.lang.String) |
|
|
|
* @see #setFieldName(String) |
|
|
|
* |
|
|
|
* |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public String getFieldName() { |
|
|
|
public String getFieldName() { |
|
|
|
return fieldName; |
|
|
|
return fieldName; |
|
|
|
} |
|
|
|
} |
|
|
@ -489,6 +455,7 @@ public class DiskFileItem |
|
|
|
* @see #getFieldName() |
|
|
|
* @see #getFieldName() |
|
|
|
* |
|
|
|
* |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public void setFieldName(String fieldName) { |
|
|
|
public void setFieldName(String fieldName) { |
|
|
|
this.fieldName = fieldName; |
|
|
|
this.fieldName = fieldName; |
|
|
|
} |
|
|
|
} |
|
|
@ -503,6 +470,7 @@ public class DiskFileItem |
|
|
|
* @see #setFormField(boolean) |
|
|
|
* @see #setFormField(boolean) |
|
|
|
* |
|
|
|
* |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public boolean isFormField() { |
|
|
|
public boolean isFormField() { |
|
|
|
return isFormField; |
|
|
|
return isFormField; |
|
|
|
} |
|
|
|
} |
|
|
@ -517,19 +485,21 @@ public class DiskFileItem |
|
|
|
* @see #isFormField() |
|
|
|
* @see #isFormField() |
|
|
|
* |
|
|
|
* |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public void setFormField(boolean state) { |
|
|
|
public void setFormField(boolean state) { |
|
|
|
isFormField = state; |
|
|
|
isFormField = state; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Returns an {@link java.io.OutputStream OutputStream} that can |
|
|
|
* Returns an {@link OutputStream OutputStream} that can |
|
|
|
* be used for storing the contents of the file. |
|
|
|
* be used for storing the contents of the file. |
|
|
|
* |
|
|
|
* |
|
|
|
* @return An {@link java.io.OutputStream OutputStream} that can be used |
|
|
|
* @return An {@link OutputStream OutputStream} that can be used |
|
|
|
* for storing the contensts of the file. |
|
|
|
* for storing the contents of the file. |
|
|
|
* |
|
|
|
* |
|
|
|
* @throws IOException if an error occurs. |
|
|
|
* @throws IOException if an error occurs. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public OutputStream getOutputStream() |
|
|
|
public OutputStream getOutputStream() |
|
|
|
throws IOException { |
|
|
|
throws IOException { |
|
|
|
if (dfos == null) { |
|
|
|
if (dfos == null) { |
|
|
@ -542,11 +512,11 @@ public class DiskFileItem |
|
|
|
// --------------------------------------------------------- Public methods
|
|
|
|
// --------------------------------------------------------- Public methods
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Returns the {@link java.io.File} object for the <code>FileItem</code>'s |
|
|
|
* Returns the {@link File} object for the <code>FileItem</code>'s |
|
|
|
* data's temporary location on the disk. Note that for |
|
|
|
* data's temporary location on the disk. Note that for |
|
|
|
* <code>FileItem</code>s that have their data stored in memory, |
|
|
|
* <code>FileItem</code>s that have their data stored in memory, |
|
|
|
* this method will return <code>null</code>. When handling large |
|
|
|
* this method will return <code>null</code>. When handling large |
|
|
|
* files, you can use {@link java.io.File#renameTo(java.io.File)} to |
|
|
|
* files, you can use {@link File#renameTo(File)} to |
|
|
|
* move the file to new location without copying the data, if the |
|
|
|
* move the file to new location without copying the data, if the |
|
|
|
* source and destination locations reside within the same logical |
|
|
|
* source and destination locations reside within the same logical |
|
|
|
* volume. |
|
|
|
* volume. |
|
|
@ -558,6 +528,9 @@ public class DiskFileItem |
|
|
|
if (dfos == null) { |
|
|
|
if (dfos == null) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (isInMemory()) { |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
return dfos.getFile(); |
|
|
|
return dfos.getFile(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -568,6 +541,9 @@ public class DiskFileItem |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected void finalize() { |
|
|
|
protected void finalize() { |
|
|
|
|
|
|
|
if (dfos == null || dfos.isInMemory()) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
File outputFile = dfos.getFile(); |
|
|
|
File outputFile = dfos.getFile(); |
|
|
|
|
|
|
|
|
|
|
|
if (outputFile != null && outputFile.exists()) { |
|
|
|
if (outputFile != null && outputFile.exists()) { |
|
|
@ -576,12 +552,15 @@ public class DiskFileItem |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Creates and returns a {@link java.io.File File} representing a uniquely |
|
|
|
* Creates and returns a {@link File File} representing a uniquely |
|
|
|
* named temporary file in the configured repository path. The lifetime of |
|
|
|
* named temporary file in the configured repository path. The lifetime of |
|
|
|
* the file is tied to the lifetime of the <code>FileItem</code> instance; |
|
|
|
* the file is tied to the lifetime of the <code>FileItem</code> instance; |
|
|
|
* the file will be deleted when the instance is garbage collected. |
|
|
|
* the file will be deleted when the instance is garbage collected. |
|
|
|
|
|
|
|
* <p> |
|
|
|
|
|
|
|
* <b>Note: Subclasses that override this method must ensure that they return the |
|
|
|
|
|
|
|
* same File each time.</b> |
|
|
|
* |
|
|
|
* |
|
|
|
* @return The {@link java.io.File File} to be used for temporary storage. |
|
|
|
* @return The {@link File File} to be used for temporary storage. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected File getTempFile() { |
|
|
|
protected File getTempFile() { |
|
|
|
if (tempFile == null) { |
|
|
|
if (tempFile == null) { |
|
|
@ -601,7 +580,7 @@ public class DiskFileItem |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Returns an identifier that is unique within the class loader used to |
|
|
|
* Returns an identifier that is unique within the class loader used to |
|
|
|
* load this class, but does not have random-like apearance. |
|
|
|
* load this class, but does not have random-like appearance. |
|
|
|
* |
|
|
|
* |
|
|
|
* @return A String with the non-random looking instance identifier. |
|
|
|
* @return A String with the non-random looking instance identifier. |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -630,83 +609,11 @@ public class DiskFileItem |
|
|
|
Boolean.valueOf(isFormField()), getFieldName()); |
|
|
|
Boolean.valueOf(isFormField()), getFieldName()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------- Serialization methods
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Writes the state of this object during serialization. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param out The stream to which the state should be written. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @throws IOException if an error occurs. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private void writeObject(ObjectOutputStream out) throws IOException { |
|
|
|
|
|
|
|
// Read the data
|
|
|
|
|
|
|
|
if (dfos.isInMemory()) { |
|
|
|
|
|
|
|
cachedContent = get(); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
cachedContent = null; |
|
|
|
|
|
|
|
dfosFile = dfos.getFile(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// write out values
|
|
|
|
|
|
|
|
out.defaultWriteObject(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Reads the state of this object during deserialization. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param in The stream from which the state should be read. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @throws IOException if an error occurs. |
|
|
|
|
|
|
|
* @throws ClassNotFoundException if class cannot be found. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private void readObject(ObjectInputStream in) |
|
|
|
|
|
|
|
throws IOException, ClassNotFoundException { |
|
|
|
|
|
|
|
if (!Boolean.getBoolean(SERIALIZABLE_PROPERTY)) { |
|
|
|
|
|
|
|
throw new IllegalStateException("Property " + SERIALIZABLE_PROPERTY |
|
|
|
|
|
|
|
+ " is not true, rejecting to deserialize a DiskFileItem."); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// read values
|
|
|
|
|
|
|
|
in.defaultReadObject(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* One expected use of serialization is to migrate HTTP sessions |
|
|
|
|
|
|
|
* containing a DiskFileItem between JVMs. Particularly if the JVMs are |
|
|
|
|
|
|
|
* on different machines It is possible that the repository location is |
|
|
|
|
|
|
|
* not valid so validate it. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
if (repository != null) { |
|
|
|
|
|
|
|
if (repository.isDirectory()) { |
|
|
|
|
|
|
|
// Check path for nulls
|
|
|
|
|
|
|
|
if (repository.getPath().contains("\0")) { |
|
|
|
|
|
|
|
throw new IOException(format( |
|
|
|
|
|
|
|
"The repository [%s] contains a null character", |
|
|
|
|
|
|
|
repository.getPath())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
throw new IOException(format( |
|
|
|
|
|
|
|
"The repository [%s] is not a directory", |
|
|
|
|
|
|
|
repository.getAbsolutePath())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OutputStream output = getOutputStream(); |
|
|
|
|
|
|
|
if (cachedContent != null) { |
|
|
|
|
|
|
|
output.write(cachedContent); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
FileInputStream input = new FileInputStream(dfosFile); |
|
|
|
|
|
|
|
IOUtils.copy(input, output); |
|
|
|
|
|
|
|
dfosFile.delete(); |
|
|
|
|
|
|
|
dfosFile = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
output.close(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cachedContent = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Returns the file item headers. |
|
|
|
* Returns the file item headers. |
|
|
|
* @return The file items headers. |
|
|
|
* @return The file items headers. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public FileItemHeaders getHeaders() { |
|
|
|
public FileItemHeaders getHeaders() { |
|
|
|
return headers; |
|
|
|
return headers; |
|
|
|
} |
|
|
|
} |
|
|
@ -715,8 +622,26 @@ public class DiskFileItem |
|
|
|
* Sets the file item headers. |
|
|
|
* Sets the file item headers. |
|
|
|
* @param pHeaders The file items headers. |
|
|
|
* @param pHeaders The file items headers. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@Override |
|
|
|
public void setHeaders(FileItemHeaders pHeaders) { |
|
|
|
public void setHeaders(FileItemHeaders pHeaders) { |
|
|
|
headers = pHeaders; |
|
|
|
headers = pHeaders; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Returns the default charset for use when no explicit charset |
|
|
|
|
|
|
|
* parameter is provided by the sender. |
|
|
|
|
|
|
|
* @return the default charset |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public String getDefaultCharset() { |
|
|
|
|
|
|
|
return defaultCharset; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Sets the default charset for use when no explicit charset |
|
|
|
|
|
|
|
* parameter is provided by the sender. |
|
|
|
|
|
|
|
* @param charset the default charset |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void setDefaultCharset(String charset) { |
|
|
|
|
|
|
|
defaultCharset = charset; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|