package net.sourceforge.solexatools.webapp.controller; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sourceforge.seqware.common.business.FileService; import net.sourceforge.seqware.common.model.File; import net.sourceforge.seqware.common.model.Registration; import net.sourceforge.seqware.common.util.Log; import net.sourceforge.seqware.common.util.filetools.FileTools; import net.sourceforge.seqware.common.util.filetools.ProvisionFilesUtil; import net.sourceforge.solexatools.Security; import net.sourceforge.solexatools.util.BulkUtil; import org.apache.commons.io.FileUtils; import org.springframework.util.FileCopyUtils; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.BaseCommandController; /** * <p> * BulkDownloaderController class. * </p> * * @author boconnor * @version $Id: $Id */ public class BulkDownloaderController extends BaseCommandController { private FileService fileService; /** Constant <code>BUFFERSIZE=500*1024</code> */ public static final int BUFFERSIZE = 500 * 1024; // 512K buffer private static final String SEPARATOR = java.io.File.separator; /** * <p> * Constructor for BulkDownloaderController. * </p> */ public BulkDownloaderController() { super(); setSupportedMethods(new String[] { METHOD_GET }); } /** * {@inheritDoc} * * @return * @throws java.lang.Exception */ @Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { Registration registration = Security.getRegistration(request); if (registration == null) return new ModelAndView("redirect:/login.htm"); // These are the files to include in the ZIP file List<File> filesToZip = BulkUtil.getFiles(request, "unknow"); if (filesToZip.isEmpty()) { return new ModelAndView("redirect:/myStudyList.htm"); } // Create the ZIP file ServletContext context = this.getServletContext(); String folderStore = context.getInitParameter("path.to.upload.directory"); String outFilename = folderStore + "outfile-" + new Date() + ".zip"; String contextPath = this.getServletContext().getContextPath(); Date dateNow = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String strNow = dateFormat.format(dateNow); String pathToTempStore = "webapps" + contextPath + SEPARATOR + "temp" + SEPARATOR + registration.getEmailAddress() + SEPARATOR + strNow + SEPARATOR; java.io.File tempStore = new java.io.File(pathToTempStore); if (!tempStore.exists()) { tempStore.mkdir(); } else { FileUtils.deleteDirectory(tempStore); tempStore.mkdir(); } ProvisionFilesUtil filesUtil = new ProvisionFilesUtil(); downloadRemoteFiles(filesUtil, filesToZip, pathToTempStore); Collection<java.io.File> filesInTemp = FileUtils.listFiles(tempStore, null, false); java.io.File out = new java.io.File(outFilename); FileTools.zipListFileRecursiveOld(new ArrayList<>(filesInTemp), out, pathToTempStore, null, false); Log.info("OUTNAME=" + outFilename); java.io.File realFile = new java.io.File(outFilename); int fileSize = (int) realFile.length(); String shortName = outFilename.substring(outFilename.lastIndexOf('/') + 1); response.setBufferSize(BUFFERSIZE); response.setContentType(this.getServletContext().getMimeType(outFilename)); response.setHeader("Content-Disposition", "attachment; filename=\"" + shortName + "\""); response.setContentLength(fileSize); try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(realFile))) { FileCopyUtils.copy(in, response.getOutputStream()); } response.getOutputStream().flush(); response.getOutputStream().close(); // delete file realFile.delete(); FileUtils.deleteDirectory(tempStore); return null; } private void downloadRemoteFiles(ProvisionFilesUtil util, List<File> filesToZip, String targetPath) throws Exception { long size = determineSize(util, filesToZip); long maxSize = getMaxBulkDownloadFilesSize(); if (size > maxSize) { throw new Exception("The files you have chosen to download total > " + maxSize + " and cannot be zipped on this web server. Please download individually."); } for (File file : filesToZip) { BufferedInputStream input = util.getSourceReader(file.getFilePath(), BUFFERSIZE, 0); util.copyToFile(input, targetPath, BUFFERSIZE, file.getFilePath()); } } private long determineSize(ProvisionFilesUtil util, List<File> filesToZip) throws Exception { long size = 0; for (File file : filesToZip) { size += ProvisionFilesUtil.getFileSize(file.getFilePath()); } return size; } private long getMaxBulkDownloadFilesSize() { ServletContext context = this.getServletContext(); String maxSizeStr = context.getInitParameter("bulk.download.max.file.size"); long maxSize = 200 * 1024 * 1024; try { maxSize = Integer.parseInt(maxSizeStr); } catch (NumberFormatException e) { e.printStackTrace(); } return maxSize; } /** * <p> * Getter for the field <code>fileService</code>. * </p> * * @return a {@link net.sourceforge.seqware.common.business.FileService} object. */ public FileService getFileService() { return fileService; } /** * <p> * Setter for the field <code>fileService</code>. * </p> * * @param fileService * a {@link net.sourceforge.seqware.common.business.FileService} object. */ public void setFileService(FileService fileService) { this.fileService = fileService; } }