package org.fenixedu.bennu.io.domain; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.google.common.io.Files; /** * * @author Shezad Anavarali Date: Jul 15, bb2009 * */ public abstract class FileStorage extends FileStorage_Base { protected FileStorage() { super(); setFileSupport(FileSupport.getInstance()); } @Override public String getName() { //FIXME: remove when the framework enables read-only slots return super.getName(); } @Override public Set<GenericFile> getFileSet() { //FIXME: remove when the framework enables read-only slots return Collections.unmodifiableSet(super.getFileSet()); } /** * Stores the given file in this storage, and associates it with the given identifier. * * This differs from the {@link #store(GenericFile, byte[])} variant in that it does not require the whole file to be loaded in * memory. * * Due to performance reasons, the given file may be locked, moved to another location or even removed. * * @param genericFile * The {@link GenericFile} instance to store * @param file * The file to store * @return * The identification associated with the newly created file * @throws IOException * If any error occurs while accessing the provided file or storing it in the underlying storage */ public String store(GenericFile genericFile, File file) throws IOException { return store(genericFile, Files.toByteArray(file)); } abstract public String store(GenericFile file, byte[] content); abstract public byte[] read(GenericFile file); abstract public InputStream readAsInputStream(GenericFile file); public static DomainStorage createNewDomainStorage(final String name) { return new DomainStorage(name); } public static LocalFileSystemStorage createNewFileSystemStorage(String name, String path, Integer treeDirectoriesNameLength) { return new LocalFileSystemStorage(name, path, treeDirectoriesNameLength); } public Boolean delete() { if (isCanBeDeleted()) { getConfigurationSet().clear(); setFileSupport(null); deleteDomainObject(); return true; } return false; } public boolean isCanBeDeleted() { return getFileSet().isEmpty(); } public boolean isDefault() { return getFileSupportAsDefault() != null; } /** * Attempts to download the given file into the given response, in a more efficient manner than loading the file into memory * and dumping it into the output stream. * * This method returns a boolean indicating whether the low-level download was performed. If not, callers are expected to * handle the file download in the regular manner. * * @param file * The file to download * @param request * The HttpServletRequest that originated the file download request * @param response * The HttpServletResponse to which the response should be written to * @param start * The start offset within the file. The value of this number MUST be between 0 and the size of the file * @param end * The end offset within the file. The value within this number MUST be between 1 and the size of the file * @return * Whether a low-level download was performed * @throws IOException * If an exception occurs while downloading the file * @throws NullPointerException * If any of the arguments is null */ public static boolean tryDownloadFile(GenericFile file, HttpServletRequest request, HttpServletResponse response, long start, long end) throws IOException { return file.getFileStorage().tryLowLevelDownload(file, request, response, start, end); } /** * Attempts to perform a low-level download of the given file into the given response. {@link FileStorage} instances are * expected to implement this whenever possible. * * The default implementation returns {@code false}, as just tells any caller to fallback to downloading the file in the * regular manner. * * @param file * The file to download * @param request * The HttpServletRequest that originated the file download request * @param response * The HttpServletResponse to which the response should be written to * @param start * The start offset within the file. The value of this number MUST be between 0 and the size of the file * @param end * The end offset within the file. The value within this number MUST be between 1 and the size of the file * @return * Whether a low-level download was performed * @throws IOException * If an exception occurs while downloading the file */ protected boolean tryLowLevelDownload(GenericFile file, HttpServletRequest request, HttpServletResponse response, long start, long end) throws IOException { return false; } }