package frame.upload.disk; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Map; import frame.upload.disk.DiskFileItem; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.DeferredFileOutputStream; import frame.upload.FileItem; import frame.upload.FileItemHeaders; import frame.upload.FileItemHeadersSupport; import frame.upload.FileUploadException; import frame.upload.ParameterParser; import frame.upload.util.Streams; public class DiskFileItem implements FileItem, FileItemHeadersSupport { private static final long serialVersionUID = 2237570099615271025L; public static final String DEFAULT_CHARSET = "ISO-8859-1"; private static final String UID = new java.rmi.server.UID().toString().replace(':', '_').replace('-', '_'); private static int counter = 0; private String fieldName; private String contentType; private boolean isFormField; private String fileName; private long size = -1; private int sizeThreshold; private File repository; private byte[] cachedContent; private transient DeferredFileOutputStream dfos; private transient File tempFile; private File dfosFile; private FileItemHeaders headers; public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { this.fieldName = fieldName; this.contentType = contentType; this.isFormField = isFormField; this.fileName = fileName; this.sizeThreshold = sizeThreshold; this.repository = repository; } public InputStream getInputStream() throws IOException { if (!isInMemory()) { return new FileInputStream(dfos.getFile()); } if (cachedContent == null) { cachedContent = dfos.getData(); } return new ByteArrayInputStream(cachedContent); } public String getContentType() { return contentType; } public String getCharSet() { ParameterParser parser = new ParameterParser(); parser.setLowerCaseNames(true); Map params = parser.parse(getContentType(), ';'); return (String) params.get("charset"); } public String getName() { return Streams.checkFileName(fileName); } public boolean isInMemory() { if (cachedContent != null) { return true; } return dfos.isInMemory(); } public long getSize() { if (size >= 0) { return size; } else if (cachedContent != null) { return cachedContent.length; } else if (dfos.isInMemory()) { return dfos.getData().length; } else { return dfos.getFile().length(); } } public byte[] get() { if (isInMemory()) { if (cachedContent == null) { cachedContent = dfos.getData(); } return cachedContent; } byte[] fileData = new byte[(int) getSize()]; FileInputStream fis = null; try { fis = new FileInputStream(dfos.getFile()); fis.read(fileData); } catch (IOException e) { fileData = null; } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { // ignore } } } return fileData; } public String getString(final String charset) throws UnsupportedEncodingException { return new String(get(), charset); } public String getString() { byte[] rawdata = get(); String charset = getCharSet(); if (charset == null) { charset = DEFAULT_CHARSET; } try { return new String(rawdata, charset); } catch (UnsupportedEncodingException e) { return new String(rawdata); } } public void write(File file) throws Exception { if (isInMemory()) { FileOutputStream fout = null; try { fout = new FileOutputStream(file); fout.write(get()); } finally { if (fout != null) { fout.close(); } } } else { File outputFile = getStoreLocation(); if (outputFile != null) { // Save the length of the file size = outputFile.length(); /* * The uploaded file is being stored on disk * in a temporary location so move it to the * desired file. */ if (!outputFile.renameTo(file)) { BufferedInputStream in = null; 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) { } } if (out != null) { try { out.close(); } catch (IOException e) { } } } } } else { /* * For whatever reason we cannot write the * file to disk. */ throw new FileUploadException( "Cannot write uploaded file to disk!"); } } } public void delete() { cachedContent = null; File outputFile = getStoreLocation(); if (outputFile != null && outputFile.exists()) { outputFile.delete(); } } public String getFieldName() { return fieldName; } public void setFieldName(String fieldName) { this.fieldName = fieldName; } public boolean isFormField() { return isFormField; } public void setFormField(boolean state) { isFormField = state; } public OutputStream getOutputStream() throws IOException { if (dfos == null) { File outputFile = getTempFile(); dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); } return dfos; } public File getStoreLocation() { return dfos == null ? null : dfos.getFile(); } protected void finalize() { File outputFile = dfos.getFile(); if (outputFile != null && outputFile.exists()) { outputFile.delete(); } } protected File getTempFile() { if (tempFile == null) { File tempDir = repository; if (tempDir == null) { tempDir = new File(System.getProperty("java.io.tmpdir")); } String tempFileName = "upload_" + UID + "_" + getUniqueId() + ".tmp"; tempFile = new File(tempDir, tempFileName); } return tempFile; } private static String getUniqueId() { final int limit = 100000000; int current; synchronized (DiskFileItem.class) { current = counter++; } String id = Integer.toString(current); // If you manage to get more than 100 million of ids, you'll // start getting ids longer than 8 characters. if (current < limit) { id = ("00000000" + id).substring(id.length()); } return id; } public String toString() { return "name=" + this.getName() + ", StoreLocation=" + String.valueOf(this.getStoreLocation()) + ", size=" + this.getSize() + "bytes, " + "isFormField=" + isFormField() + ", FieldName=" + this.getFieldName(); } 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(); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { // read values in.defaultReadObject(); 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; } public FileItemHeaders getHeaders() { return headers; } public void setHeaders(FileItemHeaders pHeaders) { headers = pHeaders; } }