001package de.deepamehta.files;
002
003import org.apache.commons.fileupload.FileItem;
004
005import java.io.File;
006import java.io.InputStream;
007
008
009
010/**
011 * An uploaded file.
012 * <p>
013 * Files are uploaded via the REST API by POSTing <code>multipart/form-data</code> to a resource method
014 * which consumes <code>multipart/form-data</code> and has UploadedFile as its entity parameter.
015 * <p>
016 * Client-side support: the public API of the Files plugin provides a method
017 * <code>dm4c.get_plugin("de.deepamehta.files").open_upload_dialog()</code> that allows the user to
018 * choose and upload a file.</p>
019 *
020 * @author <a href="mailto:jri@deepamehta.de">Jörg Richter</a>
021 */
022public class UploadedFile {
023
024    // ---------------------------------------------------------------------------------------------- Instance Variables
025
026    private FileItem fileItem;
027    private DiskQuotaCheck diskQuotaCheck;
028
029    // ---------------------------------------------------------------------------------------------------- Constructors
030
031    public UploadedFile(FileItem fileItem, DiskQuotaCheck diskQuotaCheck) {
032        this.fileItem = fileItem;
033        this.diskQuotaCheck = diskQuotaCheck;
034    }
035
036    // -------------------------------------------------------------------------------------------------- Public Methods
037
038    // === File Metadata ===
039
040    /**
041     * Returns the original filename in the client's filesystem, as provided by the browser (or other client software).
042     * In most cases, this will be the base file name, without path information. However, some clients, such as the
043     * Opera browser, do include path information.
044     */
045    public String getName() {
046        return fileItem.getName();
047    }
048
049    /**
050     * Returns the size of the file.
051     */
052    public long getSize() {
053        return fileItem.getSize();
054    }
055
056    /**
057     * Returns the content type passed by the browser or <code>null</code> if not defined.
058     */
059    public String getMediaType() {
060        return fileItem.getContentType();
061    }
062
063    // === File Content ===
064
065    /**
066     * Returns the contents of the uploaded file as a String, using the default character encoding.
067     */
068    public String getString() {
069        return fileItem.getString();
070    }
071
072    /**
073     * Returns the contents of the uploaded file as a String, using the specified encoding.
074     */
075    public String getString(String encoding) {
076        try {
077            return fileItem.getString(encoding);    // throws UnsupportedEncodingException
078        } catch (Exception e) {
079            throw new RuntimeException("Getting contents of uploaded file failed (" + this + ")", e);
080        }
081    }
082
083    /**
084     * Returns the contents of the uploaded file as an array of bytes.
085     */
086    public byte[] getBytes() {
087        return fileItem.get();
088    }
089
090    /**
091     * Returns an InputStream that can be used to retrieve the contents of the uploaded file.
092     */
093    public InputStream getInputStream() {
094        try {
095            return fileItem.getInputStream();       // throws IOException
096        } catch (Exception e) {
097            throw new RuntimeException("Getting input stream of uploaded file failed (" + this + ")", e);
098        }
099    }
100
101    // === Storage ===
102
103    /**
104     * A convenience method to write the uploaded file to disk.
105     */
106    public void write(File file) {
107        try {
108            diskQuotaCheck.check(getSize());
109            fileItem.write(file);                   // throws Exception
110        } catch (Exception e) {
111            throw new RuntimeException("Writing uploaded file to disk failed (" + this + ")", e);
112        }
113    }
114
115    // ===
116
117    @Override
118    public String toString() {
119        return "file \"" + getName() + "\" (" + getMediaType() + ", " + getSize() + " bytes)";
120    }
121}