it.geosolutions.opensdi.operations.FolderManagerOperationController.java Source code

Java tutorial

Introduction

Here is the source code for it.geosolutions.opensdi.operations.FolderManagerOperationController.java

Source

/*
 *  OpenSDI Manager
 *  Copyright (C) 2013 GeoSolutions S.A.S.
 *  http://www.geo-solutions.it
 *
 *  GPLv3 + Classpath exception
 *
 *  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 it.geosolutions.opensdi.operations;

import it.geosolutions.opensdi.utils.GeoBatchRunInfoUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.multipart.MultipartFile;

/**
 * Folder manager to extend file browser functionality. Allows to create/delete
 * folders and download files
 * 
 * @author adiaz
 */
@Controller
public class FolderManagerOperationController extends UserOperation
        implements ApplicationContextAware, ResponseManagerOperation {

    private final static Logger LOGGER = Logger.getLogger(FolderManagerOperationController.class);

    /**
     * Key for the operation to execute
     */
    private static final String FOLDER_OPERATION_KEY = "folderOperation";

    /**
     * Key for file/folder parameter
     */
    private static final String FILE_NAME_KEY = "fileName";

    /**
     * Known operation: Delete folder
     */
    private static final String DELETE_FOLDER_KEY = "delete";

    /**
     * Known operation: Download file
     */
    private static final String DOWNLOAD_KEY = "download";

    /**
     * Known operation: Create folder
     */
    private static final String CREATE_FOLDER_KEY = "create";

    // parameters from Operation
    private String operationName;
    private String operationRestPath;
    private String operationJSP;
    protected String defaultBaseDir;

    /**
     * File browser to manage
     */
    protected FileBrowserOperationController fileBrowserOperationController;

    /**
     * Create a folder manager controller for a file browser
     * 
     * @param operationName for the manager
     * @param fileBrowserOperationController file browser to manage
     */
    public FolderManagerOperationController(String operationName,
            FileBrowserOperationController fileBrowserOperationController) {
        super();
        this.operationName = operationName;
        this.operationRestPath = this.operationName;
        this.fileBrowserOperationController = fileBrowserOperationController;
        this.operationJSP = fileBrowserOperationController.getJsp();
        this.defaultBaseDir = fileBrowserOperationController.getDefaultBaseDir();
    }

    /**
     * Obtain a file to download
     */
    public void getFile(ModelMap model, HttpServletRequest request, List<MultipartFile> files,
            HttpServletResponse response) {

        String folderOperation = request.getParameter(FOLDER_OPERATION_KEY);
        String folderName = request.getParameter(FILE_NAME_KEY);
        String subFolder = request.getParameter(FileBrowserOperationController.DIRECTORY_KEY);

        if (folderOperation != null && folderName != null) {
            if (DOWNLOAD_KEY.equals(folderOperation) && fileBrowserOperationController.getCanDownloadFiles()) {
                downloadFile(folderName, subFolder, response);
            } else {
                LOGGER.error("Unknown operation " + subFolder);
            }
        }
    }

    /**
     * Manage operation on the folder and read again with
     * this.fileBrowserOperationController
     */
    public String getJsp(ModelMap model, HttpServletRequest request, List<MultipartFile> files) {

        String folderOperation = request.getParameter(FOLDER_OPERATION_KEY);
        String folderName = request.getParameter(FILE_NAME_KEY);
        String subFolder = request.getParameter(FileBrowserOperationController.DIRECTORY_KEY);

        if (folderOperation != null && folderName != null && fileBrowserOperationController.getCanManageFolders()) {
            if (DELETE_FOLDER_KEY.equals(folderOperation)) {
                deleteFolder(folderName, subFolder);
            } else if (CREATE_FOLDER_KEY.equals(folderOperation)) {
                createFolder(folderName, subFolder);
            } else {
                LOGGER.error("Unknown operation " + subFolder);
            }
        }

        fileBrowserOperationController.getJsp(model, request, files);

        return operationJSP;
    }

    /**
     * Download the file
     * 
     * @param fileName
     * @param subFolder
     * @param response
     */
    private void downloadFile(String fileName, String subFolder, HttpServletResponse response) {
        try {
            String filePath = getFilePath(fileName, subFolder);
            download(response, fileName, filePath);
        } catch (Exception ex) {
            LOGGER.info("Error writing file to output stream. Filename was '" + fileName + "'");
            throw new RuntimeException("IOError writing file to output stream");
        }
    }

    /**
     * Download a file with a stream
     * 
     * @param resp
     * @param fileName
     * @param filePath
     * @return
     */
    @SuppressWarnings("resource")
    private ResponseEntity<byte[]> download(HttpServletResponse resp, String fileName, String filePath) {

        final HttpHeaders headers = new HttpHeaders();
        File toServeUp = new File(filePath);
        InputStream inputStream = null;

        try {
            inputStream = new FileInputStream(toServeUp);
        } catch (FileNotFoundException e) {

            // Also useful, this is a good was to serve down an error message
            String msg = "ERROR: Could not find the file specified.";
            headers.setContentType(MediaType.TEXT_PLAIN);
            return new ResponseEntity<byte[]>(msg.getBytes(), headers, HttpStatus.NOT_FOUND);

        }

        resp.setContentType("application/octet-stream");
        resp.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

        Long fileSize = toServeUp.length();
        resp.setContentLength(fileSize.intValue());

        OutputStream outputStream = null;

        try {
            outputStream = resp.getOutputStream();
        } catch (IOException e) {
            String msg = "ERROR: Could not generate output stream.";
            headers.setContentType(MediaType.TEXT_PLAIN);
            return new ResponseEntity<byte[]>(msg.getBytes(), headers, HttpStatus.NOT_FOUND);
        }

        byte[] buffer = new byte[1024];

        int read = 0;
        try {

            while ((read = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, read);
            }

            // close the streams to prevent memory leaks
            outputStream.flush();
            outputStream.close();
            inputStream.close();

        } catch (Exception e) {
            String msg = "ERROR: Could not read file.";
            headers.setContentType(MediaType.TEXT_PLAIN);
            return new ResponseEntity<byte[]>(msg.getBytes(), headers, HttpStatus.NOT_FOUND);
        }

        return null;
    }

    /**
     * Create a new folder
     * 
     * @param folderName
     * @param subFolder
     */
    private void createFolder(String folderName, String subFolder) {
        String folderPath = getFilePath(folderName, subFolder);
        LOGGER.debug("Creating folder '" + folderPath + "'");
        File file = new File(folderPath);
        if (!file.exists()) {
            file.mkdir();
        } else {
            LOGGER.error("Folder '" + folderPath + "' already exists");
        }
    }

    /**
     * Delete a folder
     * 
     * @param folderName
     * @param subFolder
     */
    private void deleteFolder(String folderName, String subFolder) {
        String folderPath = getFilePath(folderName, subFolder);
        LOGGER.debug("Deleting folder '" + folderPath + "'");
        File file = new File(folderPath);
        if (file.exists()) {
            if (file.canWrite()) {
                try {
                    FileUtils.deleteDirectory(file);
                } catch (IOException e) {
                    LOGGER.error("Error deleting '" + folderPath + "' folder");
                }
            } else {
                LOGGER.error("Incorrect permissions on folder '" + folderPath + "'. We can't delete it");
            }
        } else {
            LOGGER.error("Folder '" + folderPath + "' not exists");
        }
    }

    /**
     * Obtain file path for a file in a folder inside defaultFolderDir
     * 
     * @param fileName
     * @param subFolder
     * @return
     */
    private String getFilePath(String fileName, String subFolder) {
        String filePath = defaultBaseDir;
        if (subFolder != null) {
            filePath += subFolder + GeoBatchRunInfoUtils.SEPARATOR;
        }
        filePath += fileName;
        filePath = GeoBatchRunInfoUtils.cleanDuplicateSeparators(filePath);
        return filePath;
    }

    @Override
    public String getName() {
        return operationName;
    }

    /**
     * Getter for operationName
     * 
     * @return
     */
    public String getOperationName() {
        return operationName;
    }

    /**
     * Setter for operationName
     * 
     * @param newName
     */
    public void setOperationName(String newName) {
        this.operationName = newName;
    }

    @Override
    public String getRESTPath() {
        return operationRestPath;
    }

    /**
     * @param operationRestPath the operationRestPath to set
     */
    public void setRESTPath(String operationRestPath) {
        this.operationRestPath = operationRestPath;
    }

    @Override
    public String getJsp() {
        return operationJSP;
    }

    /**
     * @return the defaultBaseDir
     */
    public String getDefaultBaseDir() {
        return defaultBaseDir;
    }

    /**
     * @param defaultBaseDir the defaultBaseDir to set
     */
    public void setDefaultBaseDir(String defaultBaseDir) {
        this.defaultBaseDir = defaultBaseDir;
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // Nothing
    }

}