org.geoserver.rest.catalog.AbstractStoreUploadController.java Source code

Java tutorial

Introduction

Here is the source code for org.geoserver.rest.catalog.AbstractStoreUploadController.java

Source

/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
 * This code is licensed under the GPL 2.0 license, available at the root
 * application directory.
 */
package org.geoserver.rest.catalog;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FilenameUtils;
import org.geoserver.catalog.Catalog;
import org.geoserver.platform.resource.Resource;
import org.geoserver.platform.resource.Resources;
import org.geoserver.rest.RestException;
import org.geoserver.rest.util.RESTUtils;
import org.geotools.util.logging.Logging;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;

public abstract class AbstractStoreUploadController extends AbstractCatalogController {

    static final Logger LOGGER = Logging.getLogger(AbstractStoreUploadController.class);

    /**
     * The ways a file upload can be achieved
     */
    protected enum UploadMethod {
        file(true), external(false), url(true);

        boolean inline;

        UploadMethod(boolean inline) {
            this.inline = inline;
        }

        public boolean isInline() {
            return inline;
        }

    }

    public AbstractStoreUploadController(Catalog catalog) {
        super(catalog);
    }

    /**
     *
     * @param store
     * @param format
     * @param directory
     *
     */
    protected List<Resource> handleFileUpload(String store, String workspace, UploadMethod method, String format,
            Resource directory, HttpServletRequest request) {

        List<Resource> files = new ArrayList<>();

        Resource uploadedFile;
        boolean external = false;
        try {
            if (method == UploadMethod.file) {
                // we want to delete the previous dir contents only in case of PUT, not
                // in case of POST (harvest, available only for raster data)
                boolean cleanPreviousContents = HttpMethod.PUT.name().equals(request.getMethod());
                String filename = request.getParameter("filename");
                if (filename == null) {
                    filename = buildUploadedFilename(store, format);
                }
                uploadedFile = RESTUtils.handleBinUpload(filename, directory, cleanPreviousContents, request,
                        workspace);
            } else if (method == UploadMethod.url) {
                uploadedFile = RESTUtils.handleURLUpload(buildUploadedFilename(store, format), workspace, directory,
                        request);
            } else if (method == UploadMethod.external) {
                uploadedFile = RESTUtils.handleEXTERNALUpload(request);
                external = true;
            } else {
                throw new RestException("Unrecognized file upload method: " + method, HttpStatus.BAD_REQUEST);
            }
        } catch (Throwable t) {
            if (t instanceof RestException) {
                throw (RestException) t;
            } else {
                throw new RestException("Error while storing uploaded file:", HttpStatus.INTERNAL_SERVER_ERROR, t);
            }
        }

        // handle the case that the uploaded file was a zip file, if so unzip it
        if (RESTUtils.isZipMediaType(request)) {
            // rename to .zip if need be
            if (!uploadedFile.name().endsWith(".zip")) {
                Resource newUploadedFile = uploadedFile.parent()
                        .get(FilenameUtils.getBaseName(uploadedFile.path()) + ".zip");
                String oldFileName = uploadedFile.name();
                if (!uploadedFile.renameTo(newUploadedFile)) {
                    String errorMessage = "Error renaming zip file from " + oldFileName + " -> "
                            + newUploadedFile.name();
                    throw new RestException(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR);
                }
                uploadedFile = newUploadedFile;
            }
            // unzip the file
            try {
                // Unzipping of the file and, if it is a POST request, filling of the File List
                RESTUtils.unzipFile(uploadedFile, directory, workspace, store, request, files, external);

                // look for the "primary" file
                // TODO: do a better check
                Resource primaryFile = findPrimaryFile(directory, format);
                if (primaryFile != null) {
                    uploadedFile = primaryFile;
                } else {
                    throw new RestException("Could not find appropriate " + format + " file in archive",
                            HttpStatus.BAD_REQUEST);
                }
            } catch (RestException e) {
                throw e;
            } catch (Exception e) {
                throw new RestException("Error occured unzipping file", HttpStatus.INTERNAL_SERVER_ERROR, e);
            }
        }
        // If the File List is empty then the uploaded file must be added
        if (uploadedFile != null) {
            files.clear();
            files.add(uploadedFile);
        }

        return files;
    }

    /**
     * Build name for an uploaded file.
     */
    private String buildUploadedFilename(String store, String format) {
        if ("h2".equalsIgnoreCase(format)) {
            return store + ".data.db";
        } else {
            return store + "." + format;
        }
    }

    /**
     * 
     * @param directory
     * @param format
     *
     */
    protected Resource findPrimaryFile(Resource directory, String format) {
        for (Resource f : Resources.list(directory, new Resources.ExtensionFilter(format.toUpperCase()), true)) {
            // assume the first
            return f;
        }
        return null;
    }

}