package org.agnitas.emm.core.download.web; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.agnitas.emm.core.download.model.FileData; import org.agnitas.emm.core.download.service.DownloadConstants; import org.agnitas.emm.core.download.service.DownloadIdNotFoundException; import org.agnitas.emm.core.download.service.DownloadService; import org.agnitas.util.FileUtils; import org.apache.log4j.Logger; import org.springframework.web.context.ContextLoader; /** * Servlet for file download. * * @author md */ public class FileDownloadServlet extends HttpServlet { /** Serial version UID. */ private static final long serialVersionUID = 7960980002662696503L; /** Logger. */ private static final transient Logger logger = Logger.getLogger( FileDownloadServlet.class); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession( false); // No session? Stop here if( session == null) { if( logger.isInfoEnabled()) logger.info( "No session data"); } // Get ID of download String downloadId = getDownloadId( req); // No ID? Stop if( downloadId == null) { if( logger.isInfoEnabled()) logger.info( "Parameter for download ID is missing"); return; } try { FileData data = getDownloadService().getDownloadData( downloadId, session); emitFile( data, resp); } catch( DownloadIdNotFoundException e) { logger.warn( "Download ID unknown: " + e.getDownloadId(), e); } } /** * Returns the download ID given at the request parameter. * * @param request HTTP request * * @return ID of download or null */ private String getDownloadId( HttpServletRequest request) { return request.getParameter( DownloadConstants.DOWNLOAD_ID_PARAMETER_NAME); } /** * Write temporary file to HTTP response. * * @param data download information * @param response HTTP response */ private void emitFile( FileData data, HttpServletResponse response) { File file = new File( data.getTempFileName()); if( !file.exists()) { logger.warn( "Temporary file for download does not exist: " + data.getTempFileName()); return; } try { FileInputStream fis = new FileInputStream( file); try { response.setContentType( data.getMimeType().toString()); if (data.getDownloadName() != null && !data.getDownloadName().isEmpty()) { response.setHeader( "Content-Disposition", "attachment; filename=\"" + data.getDownloadName() + "\";"); } @SuppressWarnings("resource") // Needed, because the container manages the stream. (Otherwise Eclipse complains about a potential resource leak) OutputStream outputStream = response.getOutputStream(); FileUtils.streamToStream( fis, file.length(), outputStream); } catch( IOException e) { logger.error( "Error sending file", e); } finally { fis.close(); } } catch( FileNotFoundException e) { logger.error( "Temporary file for download not found: " + data.getTempFileName(), e); } catch( IOException e) { logger.error( "Error sending file", e); } } // ------------------------------------------------------------------------------------------ Dependecy Injection /** * Returns the download service defined in Spring. * * @return download service */ public DownloadService getDownloadService() { // Required, because Spring cannot inject into plain servlets return (DownloadService) ContextLoader.getCurrentWebApplicationContext().getBean( "DownloadService"); } }