de.blizzy.documentr.web.attachment.AttachmentController.java Source code

Java tutorial

Introduction

Here is the source code for de.blizzy.documentr.web.attachment.AttachmentController.java

Source

/*
documentr - Edit, maintain, and present software documentation on the web.
Copyright (C) 2012-2013 Maik Schreiber
    
This program 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.
    
This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package de.blizzy.documentr.web.attachment;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import de.blizzy.documentr.DocumentrConstants;
import de.blizzy.documentr.access.AuthenticationUtil;
import de.blizzy.documentr.access.User;
import de.blizzy.documentr.access.UserStore;
import de.blizzy.documentr.page.IPageStore;
import de.blizzy.documentr.page.Page;
import de.blizzy.documentr.page.PageMetadata;
import de.blizzy.documentr.page.PageNotFoundException;
import de.blizzy.documentr.page.PageUtil;
import de.blizzy.documentr.util.Util;

@Controller
@RequestMapping("/attachment")
@Slf4j
public class AttachmentController {
    @Autowired
    private IPageStore pageStore;
    @Autowired
    private ServletContext servletContext;
    @Autowired
    private UserStore userStore;

    @RequestMapping(value = "/list/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:"
            + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{pagePath:"
            + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method = RequestMethod.GET)
    @PreAuthorize("isAuthenticated() and hasPagePermission(#projectName, #branchName, #pagePath, VIEW)")
    public String getAttachments(@PathVariable String projectName, @PathVariable String branchName,
            @PathVariable String pagePath, Model model) {

        model.addAttribute("projectName", projectName); //$NON-NLS-1$
        model.addAttribute("branchName", branchName); //$NON-NLS-1$
        pagePath = Util.toRealPagePath(pagePath);
        model.addAttribute("pagePath", pagePath); //$NON-NLS-1$
        return "/project/branch/page/attachments"; //$NON-NLS-1$
    }

    @RequestMapping(value = "/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:"
            + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{pagePath:"
            + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/"
            + "{name:.*}", method = { RequestMethod.GET, RequestMethod.HEAD })
    @PreAuthorize("hasPagePermission(#projectName, #branchName, #pagePath, VIEW)")
    public ResponseEntity<byte[]> getAttachment(@PathVariable String projectName, @PathVariable String branchName,
            @PathVariable String pagePath, @PathVariable String name,
            @RequestParam(required = false) boolean download, HttpServletRequest request) throws IOException {

        try {
            pagePath = Util.toRealPagePath(pagePath);
            PageMetadata metadata = pageStore.getAttachmentMetadata(projectName, branchName, pagePath, name);
            HttpHeaders headers = new HttpHeaders();

            long lastEdited = metadata.getLastEdited().getTime();
            long authenticationCreated = AuthenticationUtil.getAuthenticationCreationTime(request.getSession());
            long lastModified = Math.max(lastEdited, authenticationCreated);
            if (!download) {
                long projectEditTime = PageUtil.getProjectEditTime(projectName);
                if (projectEditTime >= 0) {
                    lastModified = Math.max(lastModified, projectEditTime);
                }

                long modifiedSince = request.getDateHeader("If-Modified-Since"); //$NON-NLS-1$
                if ((modifiedSince >= 0) && (lastModified <= modifiedSince)) {
                    return new ResponseEntity<byte[]>(headers, HttpStatus.NOT_MODIFIED);
                }
            }

            headers.setLastModified(lastModified);
            headers.setExpires(0);
            headers.setCacheControl("must-revalidate, private"); //$NON-NLS-1$
            if (download) {
                headers.set("Content-Disposition", //$NON-NLS-1$
                        "attachment; filename=\"" + name.replace('"', '_') + "\""); //$NON-NLS-1$ //$NON-NLS-2$
            }

            Page attachment = pageStore.getAttachment(projectName, branchName, pagePath, name);
            headers.setContentType(MediaType.parseMediaType(attachment.getContentType()));
            return new ResponseEntity<byte[]>(attachment.getData().getData(), headers, HttpStatus.OK);
        } catch (PageNotFoundException e) {
            return new ResponseEntity<byte[]>(HttpStatus.NOT_FOUND);
        }
    }

    @RequestMapping(value = "/create/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/"
            + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{pagePath:"
            + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method = RequestMethod.GET)
    @PreAuthorize("hasPagePermission(#projectName, #branchName, #pagePath, EDIT_PAGE)")
    public String createAttachment(@PathVariable String projectName, @PathVariable String branchName,
            @PathVariable String pagePath, Model model) {

        model.addAttribute("projectName", projectName); //$NON-NLS-1$
        model.addAttribute("branchName", branchName); //$NON-NLS-1$
        pagePath = Util.toRealPagePath(pagePath);
        model.addAttribute("pagePath", pagePath); //$NON-NLS-1$
        return "/project/branch/page/editAttachment"; //$NON-NLS-1$
    }

    @RequestMapping(value = "/save/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/" + "{branchName:"
            + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{pagePath:"
            + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}", method = RequestMethod.POST)
    @PreAuthorize("hasPagePermission(#projectName, #branchName, #pagePath, EDIT_PAGE)")
    public String saveAttachment(@PathVariable String projectName, @PathVariable String branchName,
            @PathVariable String pagePath, @RequestParam MultipartFile file, Authentication authentication)
            throws IOException {

        saveAttachmentInternal(projectName, branchName, pagePath, file, authentication);
        return "redirect:/attachment/list/" + projectName + "/" + branchName + "/" + pagePath; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    }

    @RequestMapping(value = "/saveViaJson/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/"
            + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{pagePath:"
            + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/json", method = RequestMethod.POST)
    @PreAuthorize("hasPagePermission(#projectName, #branchName, #pagePath, EDIT_PAGE)")
    @ResponseBody
    public Map<String, Object> saveAttachmentViaJson(@PathVariable String projectName,
            @PathVariable String branchName, @PathVariable String pagePath, @RequestParam MultipartFile file,
            Authentication authentication) throws IOException {

        log.info("saving attachment via JSON: {}", file.getOriginalFilename()); //$NON-NLS-1$
        saveAttachmentInternal(projectName, branchName, pagePath, file, authentication);

        Map<String, Object> fileResult = Maps.newHashMap();
        fileResult.put("name", file.getOriginalFilename()); //$NON-NLS-1$
        fileResult.put("size", file.getSize()); //$NON-NLS-1$
        fileResult.put("url", StringUtils.EMPTY); //$NON-NLS-1$
        fileResult.put("thumbnail_url", StringUtils.EMPTY); //$NON-NLS-1$
        fileResult.put("delete_url", StringUtils.EMPTY); //$NON-NLS-1$
        fileResult.put("delete_type", StringUtils.EMPTY); //$NON-NLS-1$
        List<Map<String, Object>> filesList = Lists.newArrayList();
        filesList.add(fileResult);
        Map<String, Object> result = Maps.newHashMap();
        result.put("files", filesList); //$NON-NLS-1$
        return result;
    }

    private void saveAttachmentInternal(String projectName, String branchName, String pagePath, MultipartFile file,
            Authentication authentication) throws IOException {

        log.debug("saving attachment: {}", file.getOriginalFilename()); //$NON-NLS-1$

        byte[] data = IOUtils.toByteArray(file.getInputStream());
        String contentType = servletContext.getMimeType(file.getOriginalFilename());
        if (StringUtils.isBlank(contentType)) {
            contentType = DocumentrConstants.DEFAULT_MIME_TYPE;
        }
        Page attachment = Page.fromData(data, contentType);
        pagePath = Util.toRealPagePath(pagePath);
        User user = userStore.getUser(authentication.getName());
        pageStore.saveAttachment(projectName, branchName, pagePath, file.getOriginalFilename(), attachment, user);
    }

    @RequestMapping(value = "/delete/{projectName:" + DocumentrConstants.PROJECT_NAME_PATTERN + "}/"
            + "{branchName:" + DocumentrConstants.BRANCH_NAME_PATTERN + "}/" + "{pagePath:"
            + DocumentrConstants.PAGE_PATH_URL_PATTERN + "}/" + "{name:.*}", method = RequestMethod.GET)
    @PreAuthorize("hasPagePermission(#projectName, #branchName, #pagePath, EDIT_PAGE)")
    public String deleteAttachment(@PathVariable String projectName, @PathVariable String branchName,
            @PathVariable String pagePath, @PathVariable String name, Authentication authentication)
            throws IOException {

        User user = userStore.getUser(authentication.getName());
        pageStore.deleteAttachment(projectName, branchName, Util.toRealPagePath(pagePath), name, user);
        return "redirect:/attachment/list/" + projectName + "/" + branchName + "/" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                Util.toUrlPagePath(pagePath);
    }
}