Package org.geoserver.wps.gs.download

Source Code of org.geoserver.wps.gs.download.DownloadProcess

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wps.gs.download;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.io.IOUtils;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.config.GeoServer;
import org.geoserver.wps.ppio.ZipArchivePPIO;
import org.geoserver.wps.resource.WPSFileResource;
import org.geoserver.wps.resource.WPSResourceManager;
import org.geotools.process.ProcessException;
import org.geotools.process.factory.DescribeParameter;
import org.geotools.process.factory.DescribeProcess;
import org.geotools.process.factory.DescribeResult;
import org.geotools.process.gs.GSProcess;
import org.geotools.util.Utilities;
import org.geotools.util.logging.Logging;
import org.opengis.filter.Filter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.util.ProgressListener;

import com.vividsolutions.jts.geom.Geometry;

/**
* The main DownloadProcess class.
*
* This class is simply responsible for deciding who is going to take care of the request and then for putting together the final result as a zip file
* adding the needed styles.
*
*
* @author "Alessio Fabiani - alessio.fabiani@geo-solutions.it"
* @author Simone Giannecchini, GeoSolutions SAS
*/
@SuppressWarnings("deprecation")
@DescribeProcess(title = "Enterprise Download Process", description = "Downloads Layer Stream and provides a ZIP.")
public class DownloadProcess implements GSProcess {

    /** The LOGGER. */
    private static final Logger LOGGER = Logging.getLogger(DownloadProcess.class);

    /** The estimator. */
    private final DownloadEstimatorProcess estimator;

    /** The catalog. */
    private final Catalog catalog;

    private WPSResourceManager resourceManager;

    /**
     * Instantiates a new download process.
     *
     * @param geoServer the geo server
     * @param sendMail the send mail
     * @param estimator the estimator
     * @param resourceManager the resourceManager to track resources to be cleaned up
     */
    public DownloadProcess(GeoServer geoServer, DownloadEstimatorProcess estimator,
            WPSResourceManager resourceManager) {
        Utilities.ensureNonNull("geoServer", geoServer);
        this.catalog = geoServer.getCatalog();
        this.estimator = estimator;
        this.resourceManager = resourceManager;
    }

    /**
     * This process returns a zipped file containing the selected layer, cropped if needed.
     *
     * @param layerName the layer name
     * @param filter the filter
     * @param email the email
     * @param mimeType the output format
     * @param targetCRS the target crs
     * @param roiCRS the roi crs
     * @param roi the roi
     * @param clip the crop to geometry
     * @param progressListener the progress listener
     * @return the file
     * @throws ProcessException the process exception
     */
    @DescribeResult(name = "result", description = "Zipped output files to download")
    public File execute(
            @DescribeParameter(name = "layerName", min = 1, description = "Original layer to download") String layerName,
            @DescribeParameter(name = "filter", min = 0, description = "Optional Vector Filter") Filter filter,
            @DescribeParameter(name = "outputFormat", min = 1, description = "Output Format Mime-Type") String mimeType,
            @DescribeParameter(name = "targetCRS", min = 0, description = "Optional Target CRS") CoordinateReferenceSystem targetCRS,
            @DescribeParameter(name = "RoiCRS", min = 0, description = "Optional Region Of Interest CRS") CoordinateReferenceSystem roiCRS,
            @DescribeParameter(name = "ROI", min = 0, description = "Optional Region Of Interest (Polygon)") Geometry roi,
            @DescribeParameter(name = "cropToROI", min = 0, description = "Crop to ROI") Boolean clip,
            final ProgressListener progressListener) throws ProcessException {

        try {

            //
            // initial checks on mandatory params
            //
            // layer name
            if (layerName == null || layerName.length() <= 0) {
                throw new IllegalArgumentException("Empty or null layerName provided!");
            }
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.log(Level.FINE, "Download process called on resource: " + layerName);
            }
            // Default behavior is intersection
            if (clip == null) {
                clip = false;
                if (LOGGER.isLoggable(Level.FINE)) {
                    LOGGER.log(Level.FINE, "Clipping disabled");
                }
            }
            // Checking the validity of the input ROI
            if (roi != null) {
                if (LOGGER.isLoggable(Level.FINE)) {
                    LOGGER.log(Level.FINE, "ROI check");
                }
                DownloadUtilities.checkPolygonROI(roi);
                if (roiCRS == null) {
                    throw new IllegalArgumentException("ROI without a CRS is not usable!");
                }
                roi.setUserData(roiCRS);
            }

            //
            // do we respect limits?
            //
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.log(Level.FINE, "Running the estimator");
            }
            if (!estimator.execute(layerName, filter, targetCRS, roiCRS, roi, clip,
                    progressListener)) {
                throw new IllegalArgumentException("Download Limits Exceeded. Unable to proceed!");
            }

            //
            // Move on with the real code
            //
            // checking for the resources on the GeoServer catalog
            LayerInfo layerInfo = catalog.getLayerByName(layerName);
            if (layerInfo == null) {
                // could not find any layer ... abruptly interrupt the process
                throw new IllegalArgumentException("Unable to locate layer: " + layerName);

            }
            ResourceInfo resourceInfo = layerInfo.getResource();
            if (resourceInfo == null) {
                // could not find any data store associated to the specified layer ... abruptly interrupt the process
                throw new IllegalArgumentException("Unable to locate ResourceInfo for layer:"
                        + layerName);

            }

            //
            // Limits
            //
            DownloadServiceConfiguration limits = estimator.getDownloadServiceConfiguration();
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.log(Level.FINE, "Employing limits " + limits);
            }
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.log(Level.FINE, "The resource to work on is " + resourceInfo.getName());
            }

            // CORE CODE
            File internalOutput = null;
            if (resourceInfo instanceof FeatureTypeInfo) {
                if (LOGGER.isLoggable(Level.FINE)) {
                    LOGGER.log(Level.FINE, "The resource to work on is a vector layer");
                }
                //
                // VECTOR
                //
                // perform the actual download of vectorial data accordingly to the request inputs
                internalOutput = new VectorDownload(limits, resourceManager).execute(
                        (FeatureTypeInfo) resourceInfo, mimeType, roi, clip, filter, targetCRS,
                        progressListener);

            } else if (resourceInfo instanceof CoverageInfo) {
                if (LOGGER.isLoggable(Level.FINE)) {
                    LOGGER.log(Level.FINE, "The resource to work on is a raster layer");
                }
                //
                // RASTER
                //
                CoverageInfo cInfo = (CoverageInfo) resourceInfo;
                // convert/reproject/crop if needed the coverage
                internalOutput = new RasterDownload(limits, resourceManager).execute(mimeType,
                        progressListener, cInfo, roi, targetCRS, clip, filter);
            } else {

                // wrong type
                throw new IllegalArgumentException(
                        "Could not complete the Download Process, requested layer was of wrong type-->"
                                + resourceInfo.getClass());

            }

            //
            // Work on result
            //
            // checks
            if (internalOutput == null) {
                // wrong type
                throw new IllegalStateException(
                        "Could not complete the Download Process, output file is null");
            }
            if (!internalOutput.exists() || !internalOutput.canRead()) {
                // wrong type
                throw new IllegalStateException(
                        "Could not complete the Download Process, output file invalid! --> "
                                + internalOutput.getAbsolutePath());

            }

            // adding the style and zipping
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.log(Level.FINE, "Preparing the result");
            }
            // build output zip
            final File result = resourceManager.getOutputFile(resourceManager.getExecutionId(true),
                    resourceInfo.getName() + ".zip");

            FileOutputStream os1 = null;
            try {
                os1 = new FileOutputStream(result);

                if (LOGGER.isLoggable(Level.FINE)) {
                    LOGGER.log(Level.FINE, "Listing files");
                }
                // output
                List<File> filesToDownload = new ArrayList<File>();
                filesToDownload.add(internalOutput);

                if (LOGGER.isLoggable(Level.FINE)) {
                    LOGGER.log(Level.FINE, "Collecting styles");
                }
                // add all SLD to zip
                List<File> styles = DownloadUtilities.collectStyles(layerInfo);
                filesToDownload.addAll(styles);

                if (LOGGER.isLoggable(Level.FINE)) {
                    LOGGER.log(Level.FINE, "Zipping files");
                }
                // zip them all
                new ZipArchivePPIO(estimator.getDownloadServiceConfiguration()
                        .getCompressionLevel()).encode(filesToDownload, os1);

            } finally {
                if (os1 != null) {
                    IOUtils.closeQuietly(os1);
                }
                if (LOGGER.isLoggable(Level.FINE)) {
                    LOGGER.log(Level.FINE, "Prepare the result for deletion");
                }
                // mark original output for deletion
                resourceManager.addResource(new WPSFileResource(internalOutput));
            }

            //
            // finishing
            //
            // Completed!
            if (progressListener != null) {
                progressListener.complete();
            }

            // return
            return result;
        } catch (Throwable e) {
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.log(Level.FINE, "Download failed");
            }
            // FAILED

            // catch and rethrow but warn the listener
            final ProcessException processException = new ProcessException(e);
            if (progressListener != null) {
                progressListener.exceptionOccurred(processException);
            }
            throw processException;
        }
    }
}
TOP

Related Classes of org.geoserver.wps.gs.download.DownloadProcess

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.