package org.smartly.packages.http.impl.handlers.servlets; import org.json.JSONArray; import org.json.JSONObject; import org.smartly.commons.cryptograph.GUID; import org.smartly.commons.image.resize.Resize; import org.smartly.commons.io.FileMeta; import org.smartly.commons.io.FileMetaArray; import org.smartly.commons.io.FileWrapper; import org.smartly.commons.util.*; import org.smartly.packages.http.impl.AbstractHttpServer; import org.smartly.packages.http.impl.WebServer; import org.smartly.packages.http.impl.util.ServletUtils; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.MultipartConfig; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.*; /** * Servlet for file upload. * Works with Jquery-Upload plugin: * https://github.com/blueimp/jQuery-File-Upload/wiki */ @MultipartConfig public class SmartlyUploadServlet extends HttpServlet { private static final String MIME_JSON = "application/json"; private final JSONObject _params; private AbstractHttpServer _server; public SmartlyUploadServlet() { _params = new JSONObject(); } public SmartlyUploadServlet(final Object params) { if (params instanceof JSONObject) { _params = (JSONObject) params; } else { _params = new JSONObject(); } } // ------------------------------------------------------------------------ // p u b l i c // ------------------------------------------------------------------------ public void setServer(final Object server) { if (server instanceof AbstractHttpServer) { _server = (AbstractHttpServer) server; } } // ------------------------------------------------------------------------ // p r o t e c t e d // ------------------------------------------------------------------------ @Override protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { final String get_file = request.getParameter("getfile") != null ? request.getParameter("getfile") : ""; final String del_file = request.getParameter("delfile") != null ? request.getParameter("delfile") : ""; final String get_thumb = request.getParameter("getthumb") != null ? request.getParameter("getthumb") : ""; if (StringUtils.hasText(get_file)) { final String tempName = getTempFullName(get_file); File file = new File(tempName); if (file.exists()) { int bytes = 0; ServletOutputStream op = response.getOutputStream(); response.setContentType(getMimeType(file)); response.setContentLength((int) file.length()); response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\""); byte[] bbuf = new byte[1024]; DataInputStream in = new DataInputStream(new FileInputStream(file)); while ((in != null) && ((bytes = in.read(bbuf)) != -1)) { op.write(bbuf, 0, bytes); } in.close(); op.flush(); op.close(); } } else if (StringUtils.hasText(del_file)) { final String tempName = getTempFullName(del_file); File file = new File(tempName); if (file.exists()) { file.delete(); // TODO:check and report success } } else if (StringUtils.hasText(get_thumb)) { final String tempName = getTempFullName(get_file); File file = new File(tempName); if (file.exists()) { System.out.println(file.getAbsolutePath()); String mimetype = getMimeType(file); if (mimetype.endsWith("png") || mimetype.endsWith("jpeg") || mimetype.endsWith("jpg") || mimetype.endsWith("gif")) { BufferedImage im = ImageIO.read(file); if (im != null) { BufferedImage thumb = Resize.resize(im, 75); ByteArrayOutputStream os = new ByteArrayOutputStream(); if (mimetype.endsWith("png")) { ImageIO.write(thumb, "PNG", os); response.setContentType("image/png"); } else if (mimetype.endsWith("jpeg")) { ImageIO.write(thumb, "jpg", os); response.setContentType("image/jpeg"); } else if (mimetype.endsWith("jpg")) { ImageIO.write(thumb, "jpg", os); response.setContentType("image/jpeg"); } else { ImageIO.write(thumb, "GIF", os); response.setContentType("image/gif"); } ServletOutputStream srvos = response.getOutputStream(); response.setContentLength(os.size()); response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\""); os.writeTo(srvos); srvos.flush(); srvos.close(); } } } // TODO: check and report success } else { PrintWriter writer = response.getWriter(); writer.write("call POST with multipart form data"); } } protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { this.handle(request, response); } // ------------------------------------------------------------------------ // p r i v a t e // ------------------------------------------------------------------------ private void handle(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { // get files and parameters final FileMetaArray files = ServletUtils.getFiles(request); final JSONObject parameters = ServletUtils.getParameters(request); final JSONObject attributes = ServletUtils.getAttributes(request); OutputStream os = null; InputStream is = null; File temp_file = null; for (final FileMeta file : files) { os = null; is = file.getContent(); if (null != is) { final String fileName = file.getName(); final String tempName = GUID.create() + PathUtils.getFilenameExtension(fileName, true); final String tempFullName = getTempFullName(tempName); try { temp_file = new File(tempFullName); os = new FileOutputStream(new File(tempFullName)); int read = 0; final byte[] buffer = new byte[1024]; while ((read = is.read(buffer)) != -1) { os.write(buffer, 0, read); } file.put("file_wrapper", new FileWrapper(temp_file).setName(fileName)); file.put("temp_url", tempFullName); // jquery-Upload response fields file.put("url", getServletUrl() + "?getfile=" + tempName); file.put("thumbnailUrl", getServletUrl() + "?getthumb=" + tempName); file.put("deleteUrl", getServletUrl() + "?delfile=" + tempName); file.put("deleteType", "GET"); file.put("thumbnail_url", getServletUrl() + "?getthumb=" + tempName); file.put("delete_url", getServletUrl() + "?delfile=" + tempName); file.put("delete_type", "GET"); } catch (Throwable t) { this.triggerOnError(FormatUtils.format("Problems during file upload. Error: {0}", t.getMessage()), t); } finally { if (os != null) { os.close(); } if (is != null) { is.close(); } } } } // prepare json output final byte[] output = this.getResponse(parameters, files); // write body ServletUtils.writeResponse(response, DateUtils.now().getTime(), MIME_JSON, output); // trigger event on server this.triggerOnUploaded(attributes, parameters, files.toJSONArray()); } private String getTempFullName(final String name) { if (null != _params && null != _server) { final String root = _server.getWorkSpacePath(JsonWrapper.getString(_params, WebServer.PARAM_MULTIPART_LOCATION)); return PathUtils.merge(root, name); } return ""; } private String getServletUrl() { if (null != _params) { return JsonWrapper.getString(_params, WebServer.PARAM_ENDPOINT); } return ""; } private void triggerOnError(final String message, final Throwable t) { if (null != _server) { _server.triggerOnError(message, t); } } private void triggerOnUploaded(final JSONObject attributes, final JSONObject parameters, final JSONArray files) { if (null != _server && files.length() > 0) { _server.triggerOnUploaded(attributes, parameters, files); } } private String getMimeType(File file) { String mimetype = ""; if (file.exists()) { if (getSuffix(file.getName()).equalsIgnoreCase("png")) { mimetype = "image/png"; } else if (getSuffix(file.getName()).equalsIgnoreCase("jpg")) { mimetype = "image/jpg"; } else if (getSuffix(file.getName()).equalsIgnoreCase("jpeg")) { mimetype = "image/jpeg"; } else if (getSuffix(file.getName()).equalsIgnoreCase("gif")) { mimetype = "image/gif"; } else { javax.activation.MimetypesFileTypeMap mtMap = new javax.activation.MimetypesFileTypeMap(); mimetype = mtMap.getContentType(file); } } return mimetype; } private String getSuffix(String filename) { String suffix = ""; int pos = filename.lastIndexOf('.'); if (pos > 0 && pos < filename.length() - 1) { suffix = filename.substring(pos + 1); } return suffix; } private byte[] getResponse(final JSONObject parameters, final FileMetaArray files) { final String response = JsonWrapper.getString(parameters, "response"); if (StringUtils.hasText(response)) { return response.getBytes(); } else { return files.toString().getBytes(); } } }