package org.aplikator.server; import javax.activation.MimeTypeParseException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.util.logging.Logger; import org.apache.commons.fileupload.util.Streams; import org.apache.commons.io.IOUtils; import org.aplikator.client.local.widgets.BinaryFieldWidget; import org.aplikator.client.shared.data.PrimaryKey; import org.aplikator.server.data.AplikatorServiceBackend; import org.aplikator.server.data.BinaryData; import org.aplikator.server.data.Context; import org.aplikator.server.descriptor.BinaryProperty; import org.aplikator.server.descriptor.Entity; import org.aplikator.server.persistence.PersisterFactory; @WebServlet( name = "FileDownloadServlet", urlPatterns = {"/download"}) public class FileDownloadServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; private static final Logger LOG = Logger.getLogger(FileDownloadServlet.class.getName()); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setCharacterEncoding("UTF-8"); String entityId = req.getParameter(BinaryFieldWidget.ENTITY_ID); String propertyId = req.getParameter(BinaryFieldWidget.PROPERTY_ID); int primaryKey = Integer.parseInt(req.getParameter(BinaryFieldWidget.PRIMARY_KEY_ID)); int maxSize = Integer.parseInt(req.getParameter(BinaryFieldWidget.MAXSIZE_ID)); boolean attachment = false; String attachmentPar = req.getParameter(BinaryFieldWidget.ATTACHMENT_ID); if (attachmentPar != null) { attachment = Boolean.parseBoolean(attachmentPar); } Entity entity = (Entity) DescriptorRegistry.get().getDescriptionItem(entityId); @SuppressWarnings("unchecked") BinaryProperty property = (BinaryProperty) DescriptorRegistry.get().getDescriptionItem(propertyId); BinaryData blob = PersisterFactory.getPersister().getBlob(entity, property, primaryKey, maxSize); if (maxSize == BinaryFieldWidget.FULL_SIZE_ATTACHMENT_CODE) { attachment = true; resp.setContentType("application/octet-stream"); } else if (maxSize == BinaryFieldWidget.FULL_SIZE_IMAGE_CODE) { try { resp.setContentType(ImageResizer.getMimeType(blob.properties.get("filename")).toString()); } catch (MimeTypeParseException e) { resp.setContentType("application/octet-stream"); } } else { resp.setContentType("image/jpeg"); } resp.setHeader("Cache-Control", "no-cache"); resp.setHeader("Pragma", "no-cache"); if (attachment) { String filename = "unnamed"; try { String rawfilename = blob.properties.get("filename"); if (property.getTriggers() != null) { AplikatorServiceBackend aplikatorServiceBackend = new AplikatorServiceBackend(); Context ctx = new Context(req, resp, aplikatorServiceBackend, null); try { rawfilename = property.getTriggers().processFileName(rawfilename, new PrimaryKey(entityId, primaryKey), property, ctx); } finally { ctx.closeTransaction(); } } String encodedfilename = URLEncoder.encode(rawfilename, "UTF-8"); filename = encodedfilename.replace("+", " "); } catch (Exception e) { LOG.warning("Error encoding filename: " + e); } resp.setHeader("Content-disposition", "attachment; filename*=UTF-8''" + filename); } if (blob.inputStream != null) { OutputStream os = resp.getOutputStream(); Streams.copy(blob.inputStream, os, true); os.flush(); } else if (blob.properties.isEmpty()) { OutputStream os = resp.getOutputStream(); Streams.copy(IOUtils.toInputStream("EMPTY", "UTF-8"), os, true); os.flush(); } else { resp.setContentType("image/png"); OutputStream os = resp.getOutputStream(); InputStream icon = this.getClass().getResourceAsStream("/genericFileIcon.png"); Streams.copy(icon, os, true); os.flush(); } } }