package onlinefrontlines.utils; import java.io.*; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import javax.servlet.http.*; import java.util.List; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; /** * Class that stores images uploaded by users * * @author jorrit * * Copyright (C) 2009-2013 Jorrit Rouwe * * This file is part of Online Frontlines. * * Online Frontlines is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Online Frontlines is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Online Frontlines. If not, see <http://www.gnu.org/licenses/>. */ public class UploadedImageManager { /** * Singleton instance */ private static UploadedImageManager instance = new UploadedImageManager(); /** * Maximum image size */ private static final int MAX_FILE_SIZE = 25 * 1024; /** * Exception generated by adding images */ public static class AddException extends Exception { private static final long serialVersionUID = 0; public AddException(String message) { super(message); } } /** * Supported image type */ private static class ImageType { public String contentType; public String extension; public ImageType(String contentType, String extension) { this.contentType = contentType; this.extension = extension; } } /** * Supported types */ private static ImageType[] supportedTypes = { new ImageType("image/png", "png"), new ImageType("image/x-png", "png"), new ImageType("image/jpeg", "jpg"), new ImageType("image/pjpeg", "jpg"), new ImageType("image/bmp", "bmp"), new ImageType("image/gif", "gif") }; /** * Singleton access */ public static UploadedImageManager getInstance() { return instance; } /** * Add new image to the server * * @param prefix Prefix for the image * @param id Id for the image * @param in Input stream that contains the image data * @param contentType File type of the image * @throws AddException */ public void addImage(String prefix, int id, InputStream in, String contentType) throws AddException { // Find type ImageType type = null; for (ImageType t : supportedTypes) if (t.contentType.equals(contentType)) { type = t; break; } if (type == null) throw new AddException("invalidFileType"); // Remove previous image removeImage(prefix, id); try { // Copy file String outFileName = GlobalProperties.getInstance().getString("images.folder") + "/" + prefix + "_" + Integer.toString(id) + "." + type.extension; File outFile = new File(outFileName); OutputStream out = new FileOutputStream(outFile); try { byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) out.write(buf, 0, len); } finally { out.close(); } } catch (IOException e) { throw new AddException("failedFileUpload"); } } /** * Add image from http request * * @param prefix Prefix for the image * @param id Id for the image * @param request Request that contains the image data * @param width Max with for the image * @param height Max height for the image * @throws AddException */ @SuppressWarnings("unchecked") public void addImage(String prefix, int id, HttpServletRequest request, int width, int height) throws AddException { try { // Get files from request DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(MAX_FILE_SIZE); ServletFileUpload upload = new ServletFileUpload(factory); upload.setSizeMax(MAX_FILE_SIZE); List<FileItem> items = (List<FileItem>)upload.parseRequest(request); // Find correct attachment for (FileItem item : items) if (!item.isFormField()) { // Skip file uploads that don't have a file name - meaning that no file was selected. if (item.getName() == null || item.getName().trim().length() < 1) continue; try { // Read image to see if it is correct InputStream is = item.getInputStream(); try { BufferedImage image = ImageIO.read(is); if (image == null) throw new AddException("imageCorrupt"); if (image.getHeight() != height || image.getWidth() != width) throw new AddException("invalidResolution"); } finally { is.close(); } // Add the image is = item.getInputStream(); try { addImage(prefix, id, is, item.getContentType()); } finally { is.close(); } break; } catch (IOException e) { throw new AddException("imageCorrupt"); } } } catch (FileUploadException e) { throw new AddException("failedFileUpload"); } } /** * Remove previously uploaded image * * @param prefix Prefix for the image * @param id Id for the image */ public void removeImage(String prefix, int id) { // Find image String imageName = prefix + "_" + Integer.toString(id); for (ImageType t : supportedTypes) { String fullName = imageName + "." + t.extension; new File(GlobalProperties.getInstance().getString("images.folder") + "/" + fullName).delete(); } } /** * Get URL to pass to the web page for downloading the image * * @param prefix Prefix for the image * @param id Id of the image * @return Path relative to the webapp */ public String getImageURL(String prefix, int id) { // Find image String imageName = prefix + "_" + Integer.toString(id); for (ImageType t : supportedTypes) { String fullName = imageName + "." + t.extension; if (new File(GlobalProperties.getInstance().getString("images.folder") + "/" + fullName).exists()) return GlobalProperties.getInstance().getString("images.url") + "/" + fullName; } // Not found return GlobalProperties.getInstance().getString("images.url") + "/" + prefix + "_dummy.gif"; } }