fr.treeptik.cloudunit.controller.FileController.java Source code

Java tutorial

Introduction

Here is the source code for fr.treeptik.cloudunit.controller.FileController.java

Source

/*
 * LICENCE : CloudUnit is available under the GNU Affero General Public License : https://gnu.org/licenses/agpl.html
 * but CloudUnit is licensed too under a standard commercial license.
 * Please contact our sales team if you would like to discuss the specifics of our Enterprise license.
 * If you are not sure whether the AGPL is right for you,
 * you can always test our software under the AGPL and inspect the source code before you contact us
 * about purchasing a commercial license.
 *
 * LEGAL TERMS : "CloudUnit" is a registered trademark of Treeptik and can't be used to endorse
 * or promote products derived from this project without prior written permission from Treeptik.
 * Products or services derived from this software may not be called "CloudUnit"
 * nor may "Treeptik" or similar confusing terms appear in their names without prior written permission.
 * For any questions, contact us : contact@treeptik.fr
 */

package fr.treeptik.cloudunit.controller;

import fr.treeptik.cloudunit.dto.FileUnit;
import fr.treeptik.cloudunit.dto.HttpOk;
import fr.treeptik.cloudunit.dto.JsonResponse;
import fr.treeptik.cloudunit.exception.CheckException;
import fr.treeptik.cloudunit.exception.ServiceException;
import fr.treeptik.cloudunit.model.Application;
import fr.treeptik.cloudunit.model.Status;
import fr.treeptik.cloudunit.model.User;
import fr.treeptik.cloudunit.service.ApplicationService;
import fr.treeptik.cloudunit.service.FileService;
import fr.treeptik.cloudunit.utils.AuthentificationUtils;
import fr.treeptik.cloudunit.utils.FilesUtils;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Locale;
import java.util.Optional;

/*
 * Controller for resources (files + folders) into Container.
 *
 * TODO : ADD Status Application management. UseCase : disable user action durant long time download/upload
 *
 * Created by nicolas on 20/05/15.
 */

@Controller
@RequestMapping("/file")
public class FileController {

    private static final long serialVersionUID = 1L;

    private final transient Logger logger = LoggerFactory.getLogger(FileController.class);

    @Inject
    private FileService fileService;

    @Inject
    private ApplicationService applicationService;

    @Inject
    private AuthentificationUtils authentificationUtils;

    private Locale locale = Locale.ENGLISH;

    /**
     * @param containerId
     * @param path
     * @return
     * @throws ServiceException
     * @throws CheckException
     */
    @RequestMapping(value = "/container/{containerId}/path/{path}", method = RequestMethod.GET)
    public @ResponseBody List<FileUnit> listByContainerIdAndPath(@PathVariable String containerId,
            @PathVariable String path) throws ServiceException, CheckException {

        if (logger.isInfoEnabled()) {
            logger.info("containerId:" + containerId);
            logger.info("path:" + path);
        }

        path = convertPathFromUI(path);
        List<FileUnit> fichiers = fileService.listByContainerIdAndPath(containerId, path);

        return fichiers;
    }

    /**
     * Upload a file into a container
     *
     * @return
     * @throws IOException
     * @throws ServiceException
     * @throws CheckException
     */
    @RequestMapping(value = "/container/{containerId}/application/{applicationName}/path/{path}", method = RequestMethod.POST, consumes = {
            "multipart/form-data" })
    public @ResponseBody JsonResponse uploadFileToContainer(@RequestPart("file") MultipartFile fileUpload,
            @PathVariable final String containerId, @PathVariable final String applicationName,
            @PathVariable final String path, HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServiceException, CheckException {

        if (logger.isDebugEnabled()) {
            logger.debug("-- CALL UPLOAD FILE TO CONTAINER FS --");
            logger.debug("applicationName = " + applicationName);
            logger.debug("containerId = " + containerId);
            logger.debug("pathFile = " + path);
        }

        User user = authentificationUtils.getAuthentificatedUser();
        Application application = applicationService.findByNameAndUser(user, applicationName);

        // We must be sure there is no running action before starting new one
        this.authentificationUtils.canStartNewAction(user, application, locale);

        // Application is now pending
        applicationService.setStatus(application, Status.PENDING);

        if (application != null) {
            File file = File.createTempFile("upload-", FilesUtils.setSuffix(fileUpload.getOriginalFilename()));
            fileUpload.transferTo(file);

            try {
                fileService.sendFileToContainer(applicationName, containerId, file,
                        fileUpload.getOriginalFilename(), path);

            } catch (ServiceException e) {
                logger.error("Error during file upload : " + file);
                logger.error("containerId : " + containerId);
                logger.error("applicationName : " + applicationName);

            } finally {
                // in all case, the error during file upload cannot be critical.
                // We prefer to set the application in started mode
                applicationService.setStatus(application, Status.START);
            }
        }

        return new HttpOk();

    }

    /**
     * Delete resources (files and folders) into a container for a path
     *
     * @param containerId
     * @param applicationName
     * @param path
     * @return
     * @throws ServiceException
     * @throws CheckException
     * @throws IOException
     */
    @RequestMapping(value = "/container/{containerId}/application/{applicationName}/path/{path:.*}", method = RequestMethod.DELETE)
    public @ResponseBody JsonResponse deleteResourcesIntoContainer(@PathVariable final String containerId,
            @PathVariable final String applicationName, @PathVariable String path)
            throws ServiceException, CheckException, IOException {

        if (logger.isDebugEnabled()) {
            logger.debug("containerId:" + containerId);
            logger.debug("applicationName:" + applicationName);
            logger.debug("path:" + path);
        }

        path = convertPathFromUI(path);
        User user = authentificationUtils.getAuthentificatedUser();
        Application application = applicationService.findByNameAndUser(user, applicationName);

        fileService.deleteFilesFromContainer(applicationName, containerId, path);

        return new HttpOk();
    }

    /**
     * Download a file into a container
     *
     * @param containerId
     * @param applicationName
     * @param path
     * @param fileName
     * @param request
     * @param response
     * @throws ServiceException
     * @throws CheckException
     * @throws IOException
     * @returnoriginalName
     */
    @RequestMapping(value = "/container/{containerId}/application/{applicationName}/path/{path}/fileName/{fileName:.*}", method = RequestMethod.GET)
    public void downloadFileFromContainer(@PathVariable final String containerId,
            @PathVariable final String applicationName, @PathVariable String path,
            @PathVariable final String fileName, HttpServletRequest request, HttpServletResponse response)
            throws ServiceException, CheckException, IOException {

        if (logger.isDebugEnabled()) {
            logger.debug("containerId:" + containerId);
            logger.debug("applicationName:" + applicationName);
            logger.debug("fileName:" + fileName);
        }

        User user = authentificationUtils.getAuthentificatedUser();
        Application application = applicationService.findByNameAndUser(user, applicationName);

        // We must be sure there is no running action before starting new one
        this.authentificationUtils.canStartNewAction(user, application, locale);

        File file = File.createTempFile("previousDownload", FilesUtils.setSuffix(fileName));

        path = convertPathFromUI(path);
        Optional<File> fileFromContainer = fileService.getFileFromContainer(applicationName, containerId, file,
                fileName, path);

        // File can be empty but we need to return one
        if (fileFromContainer.filter(x -> x.length() == 0).isPresent()) {
            file = File.createTempFile(fileName, "");
            // put an empty space for empty file
            FileUtils.write(file, " ");
        }

        InputStream inputStream = new FileInputStream(file); //load the file
        IOUtils.copy(inputStream, response.getOutputStream());
        response.flushBuffer();

    }

    private String convertPathFromUI(String path) {
        if (path != null) {
            path = path.replaceAll("____", "/");
            path = path.replaceAll("__", "/");
        }
        return path;
    }
}