/* * Copyright (c) JForum Team. All rights reserved. * * The software in this package is published under the terms of the LGPL * license a copy of which has been included with this distribution in the * license.txt file. * * The JForum Project * http://www.jforum.net */ package net.jforum.services; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.List; import javax.servlet.http.HttpServletRequest; import net.jforum.actions.helpers.AttachedFile; import net.jforum.core.exceptions.ForumException; import net.jforum.entities.Attachment; import net.jforum.entities.Post; import net.jforum.repository.AttachmentRepository; import net.jforum.util.ConfigKeys; import net.jforum.util.ImageUtils; import net.jforum.util.JForumConfig; import net.jforum.util.MD5; import net.jforum.util.UploadUtils; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import br.com.caelum.vraptor.interceptor.multipart.UploadedFile; import br.com.caelum.vraptor.ioc.Component; /** * @author Rafael Steil */ @Component public class AttachmentService { private static Logger logger = Logger.getLogger(AttachmentService.class); private final JForumConfig config; private final AttachmentRepository repository; public AttachmentService(JForumConfig config, AttachmentRepository repository) { this.config = config; this.repository = repository; } public Attachment getAttachmentForDownload(int attachmentId) { Attachment attachment = this.repository.get(attachmentId); attachment.incrementDownloadCount(); return attachment; } public List<AttachedFile> processNewAttachments(HttpServletRequest request) { String t = request.getParameter("total_attachments"); List<AttachedFile> attachedFiles = new ArrayList<AttachedFile>(); if (StringUtils.isEmpty(t)) { return attachedFiles; } int total = Integer.parseInt(t); if (total < 1) { return attachedFiles; } long totalSize = 0; for (int i = 0; i < total; i++) { UploadedFile fileInfo = (UploadedFile) request.getAttribute("attachment_" + i); if (fileInfo == null) { continue; } if (fileInfo.getFileName().indexOf('\000') > -1) { logger.warn("Possible bad attachment (null char): " + fileInfo.getFileName()); continue; } UploadUtils uploadUtils = new UploadUtils(fileInfo); String description = request.getParameter("attachment_description_" + i); Attachment attachment = new Attachment(); try { attachment.setFilesize(fileInfo.getFile().available()); } catch (IOException e) { throw new ForumException(e); } attachment.setDescription(description); attachment.setMimetype(fileInfo.getContentType()); // Get only the filename, without the path (IE does that) String realName = this.stripPath(fileInfo.getFileName()); attachment.setRealFilename(realName); attachment.setUploadDate(new Date()); attachment.setFileExtension(uploadUtils.getExtension()); String savePath = this.buildStoreFilename(attachment); attachment.setPhysicalFilename(savePath); attachedFiles.add(new AttachedFile(attachment, uploadUtils)); totalSize += attachment.getFilesize(); } return attachedFiles; } /** * @param realName String * @return String */ public String stripPath(String realName) { String separator = "/"; int index = realName.lastIndexOf(separator); if (index == -1) { separator = "\\"; index = realName.lastIndexOf(separator); } if (index > -1) { realName = realName.substring(index + 1); } return realName; } public void insertAttachments(List<AttachedFile> attachedFiles, Post post) { if (attachedFiles.size() > 0) { post.setHasAttachments(true); for (AttachedFile attachedFile : attachedFiles) { String path = this.config.getValue(ConfigKeys.ATTACHMENTS_STORE_DIR) + "/" + attachedFile.getAttachment().getPhysicalFilename(); attachedFile.getUploadUtils().saveUploadedFile(path); if (this.shouldCreateThumb(attachedFile.getAttachment())) { attachedFile.getAttachment().setHasThumb(true); this.createSaveThumb(path); } post.addAttachment(attachedFile.getAttachment()); } } } private boolean shouldCreateThumb(Attachment attachment) { String extension = attachment.getFileExtension(); return this.config.getBoolean(ConfigKeys.ATTACHMENTS_IMAGES_CREATE_THUMB) && ("jpg".equals(extension) || "jpeg".equals(extension) || "gif".equals(extension) || "png".equals(extension)); } private void createSaveThumb(String path) { try { BufferedImage image = ImageUtils.resizeImage(path, ImageUtils.IMAGE_JPEG, this.config.getInt(ConfigKeys.ATTACHMENTS_IMAGES_MAX_THUMB_W), this.config.getInt(ConfigKeys.ATTACHMENTS_IMAGES_MAX_THUMB_H)); ImageUtils.saveImage(image, path + "_thumb", ImageUtils.IMAGE_JPEG); } catch (Exception e) { logger.error(e.toString(), e); } } public void editAttachments(Post post, HttpServletRequest request) { // Check for attachments to remove List<String> deleteList = new ArrayList<String>(); String[] delete = null; String s = request.getParameter("delete_attach"); if (!StringUtils.isEmpty(s)) { delete = s.split(","); } if (!ArrayUtils.isEmpty(delete)) { for (String deleteId : delete) { if (!StringUtils.isEmpty(deleteId)) { int attachmentId = Integer.parseInt(deleteId); Attachment attachment = this.repository.get(attachmentId); post.getAttachments().remove(attachment); this.removeAttachmentFiles(attachment); } } deleteList = Arrays.asList(delete); } // Update String[] attachIds = null; s = request.getParameter("edit_attach_ids"); if (!StringUtils.isEmpty(s)) { attachIds = s.split(","); } if (!ArrayUtils.isEmpty(attachIds)) { for (String x : attachIds) { if (deleteList.contains(x) || StringUtils.isEmpty(x)) { continue; } int attachmentId = Integer.parseInt(x); Attachment attachment = this.repository.get(attachmentId); attachment.setDescription(request.getParameter("edit_description_" + attachmentId)); } } } public void deleteAllAttachments(Post post) { for (Attachment attachment : post.getAttachments()) { this.removeAttachmentFiles(attachment); } } private void removeAttachmentFiles(Attachment attachment) { String filename = this.buildDownloadPath(attachment); File f = new File(filename); if (f.exists()) { f.delete(); } // Check if we have a thumb to delete f = new File(filename + "_thumb"); if (f.exists()) { f.delete(); } } private String buildStoreFilename(Attachment attachment) { int year = Calendar.getInstance().get(Calendar.YEAR); int month = Calendar.getInstance().get(Calendar.MONTH) + 1; int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH); StringBuilder dir = new StringBuilder(256); dir.append(year).append('/').append(month).append('/').append(day).append('/'); new File(this.config.getValue(ConfigKeys.ATTACHMENTS_STORE_DIR) + "/" + dir).mkdirs(); return dir.append(MD5.hash(attachment.getRealFilename() + System.currentTimeMillis())) .append('.').append(attachment.getFileExtension()) .toString(); } public String buildDownloadPath(Attachment attachment) { return String.format("%s/%s", this.config.getValue(ConfigKeys.ATTACHMENTS_STORE_DIR), attachment.getPhysicalFilename()); } }