net.jforum.services.AttachmentService.java Source code

Java tutorial

Introduction

Here is the source code for net.jforum.services.AttachmentService.java

Source

/*
 * 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());
    }
}