Package org.geoserver.catalog.rest

Source Code of org.geoserver.catalog.rest.CoverageStoreFileResource

/* (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.catalog.rest;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.CoverageStoreInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.SingleGridCoverage2DReader;
import org.geoserver.rest.RestletException;
import org.geoserver.rest.format.DataFormat;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.coverage.grid.io.GridCoverage2DReader;
import org.geotools.coverage.grid.io.StructuredGridCoverage2DReader;
import org.geotools.data.DataUtilities;
import org.geotools.factory.GeoTools;
import org.opengis.coverage.grid.Format;
import org.opengis.coverage.grid.GridCoverageReader;
import org.restlet.data.Form;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;

public class CoverageStoreFileResource extends StoreFileResource {

    Format coverageFormat;
   
    public CoverageStoreFileResource(Request request, Response response,
            Format coverageFormat, Catalog catalog) {
        super(request, response, catalog);
        this.coverageFormat = coverageFormat;
    }

    /**
     * Post is allowed only if the reader in question is structured and can do harvesting
     */
    @Override
    public boolean allowPost() {
        String workspace = getAttribute("workspace");
        String coveragestore = getAttribute("coveragestore");
       
        // check the coverage store exists
        CoverageStoreInfo info = catalog.getCoverageStoreByName(workspace, coveragestore);
        if(info == null) {
            return false;
        }

        try {
            GridCoverageReader reader = info.getGridCoverageReader(null, null);
            if(reader instanceof StructuredGridCoverage2DReader) {
                StructuredGridCoverage2DReader sr = (StructuredGridCoverage2DReader) reader;
                return !sr.isReadOnly();
            } else {
                return false;
            }
        } catch(IOException e) {
            throw new RestletException("Failed to access the existing reader to " +
                "check if it can harvest new files", Status.SERVER_ERROR_INTERNAL);
        }
    }
   
    @Override
    public void handlePost() {
        String workspace = getAttribute("workspace");
        String coveragestore = getAttribute("coveragestore");
        String format = getAttribute("format");
        Request request = getRequest();
        String method = getUploadMethod(request);

       
        // theoretically allowPost was just called, so all these should not need a check
        try {
            CoverageStoreInfo info = catalog.getCoverageStoreByName(workspace, coveragestore);
            GridCoverageReader reader = info.getGridCoverageReader(null, null);
            StructuredGridCoverage2DReader sr = (StructuredGridCoverage2DReader) reader;
            // This method returns a List of the harvested files.
            final List<File> uploadedFiles = doFileUpload(method, workspace, coveragestore, format);
            // File Harvesting
            sr.harvest(null, uploadedFiles, GeoTools.getDefaultHints());
        } catch(IOException e) {
            throw new RestletException("File harvest failed", Status.SERVER_ERROR_INTERNAL, e);
        }
    }
   
    @Override
    public void handlePut() {
        Request request = getRequest();
        Response response = getResponse();
       
        String workspace = getAttribute("workspace");
        String coveragestore = getAttribute("coveragestore");
        String format = getAttribute("format");
        String method = getUploadMethod(request);
       
        // doFileUpload returns a List of File but in the case of a Put operation the list contains only a value
        final File uploadedFile = doFileUpload(method, workspace, coveragestore, format).get(0);
       
        // /////////////////////////////////////////////////////////////////////
        //
        // Add overviews to the Coverage
        //
        // /////////////////////////////////////////////////////////////////////
        Form form = request.getResourceRef().getQueryAsForm();
        if ("yes".equalsIgnoreCase(form.getFirstValue("overviews")) ) {
            /* TODO: Add overviews here */;
        }
           
        //create a builder to help build catalog objects
        CatalogBuilder builder = new CatalogBuilder(catalog);
        builder.setWorkspace( catalog.getWorkspaceByName( workspace ) );
       
        //create the coverage store
        CoverageStoreInfo info = catalog.getCoverageStoreByName(workspace, coveragestore);
        boolean add = false;
        if ( info == null ) {
            //create a new coverage store
            LOGGER.info("Auto-configuring coverage store: " + coveragestore);
           
            info = builder.buildCoverageStore(coveragestore);
            add = true;
        }
        else {
            //use the existing
            LOGGER.info("Using existing coverage store: " + coveragestore);
        }
       
        info.setType(coverageFormat.getName());
        URL uploadedFileURL = DataUtilities.fileToURL(uploadedFile);
        if (isInlineUpload(method)) {
            //TODO: create a method to figure out the relative url instead of making assumption
            // about the structure
           
            String defaultRoot = File.separator + "data" + File.separator + workspace + File.separator + coveragestore;
           
            StringBuilder fileBuilder = new StringBuilder(uploadedFile.getAbsolutePath());
           
            String url;
            if(uploadedFile.isDirectory() && uploadedFile.getName().equals(coveragestore)) {

                int def = fileBuilder.indexOf(defaultRoot);
               
                if(def >= 0){
                    url = "file:data/" + workspace + "/" + coveragestore;
                }else{
                    url = fileBuilder.toString();
                }
            } else {

                int def = fileBuilder.indexOf(defaultRoot);
               
                if(def >= 0){
                   
                    String itemPath = fileBuilder.substring(def + defaultRoot.length());
                   
                    url = "file:data/" + workspace + "/" + coveragestore + "/" + itemPath;
                }else{
                    url = fileBuilder.toString();
                }
            }
            if (url.contains("+")) {
                url = url.replace("+", "%2B");
            }
            if (url.contains(" ")) {
                url = url.replace(" ", "%20");
            }
            info.setURL(url);
        }
        else {
            info.setURL( uploadedFileURL.toExternalForm());
        }
       
        //add or update the datastore info
        if ( add ) {
          if (!catalog.validate(info, true).isValid()) {
            throw new RuntimeException("Validation failed");
          }
            catalog.add( info );
        }
        else {
          if (!catalog.validate(info, false).isValid()) {
            throw new RuntimeException("Validation failed");
          }
            catalog.save( info );
        }
       
        builder.setStore(info);
       
        //check configure parameter, if set to none to not try to configure coverage
        String configure = form.getFirstValue( "configure" );
        if ( "none".equalsIgnoreCase( configure ) ) {
            getResponse().setStatus( Status.SUCCESS_CREATED );
            return;
        }
       
        GridCoverage2DReader reader = null;
        try {
            reader =
                (GridCoverage2DReader) ((AbstractGridFormat) coverageFormat).getReader(DataUtilities.fileToURL(uploadedFile));
            if ( reader == null ) {
                throw new RestletException( "Could not aquire reader for coverage.", Status.SERVER_ERROR_INTERNAL);
            }
           
            // coverage read params
            final Map customParameters = new HashMap();
            String useJAIImageReadParam = form.getFirstValue("USE_JAI_IMAGEREAD");
            if (useJAIImageReadParam != null) {
              customParameters.put(AbstractGridFormat.USE_JAI_IMAGEREAD.getName().toString(), Boolean.valueOf(useJAIImageReadParam));
            }
           
            //check if the name of the coverage was specified
            String coverageName = form.getFirstValue("coverageName");
            String[] names = reader.getGridCoverageNames();
           
            if(names.length > 1 && coverageName != null) {
                throw new RestletException("The reader found more than one coverage, " +
                    "coverageName cannot be used in this case (it would generate " +
                    "the same name for all coverages found", Status.CLIENT_ERROR_BAD_REQUEST);
            }
           
            // configure all available coverages, preserving backwards compatibility for the
            // case of single coverage reader
            if(names.length > 1) {
                for (String name : names) {
                    SingleGridCoverage2DReader singleReader = new SingleGridCoverage2DReader(reader, name);
                    configureCoverageInfo(builder, info, add, name, name, singleReader,
                            customParameters);
                }
            } else {
                configureCoverageInfo(builder, info, add, names[0], coverageName, reader,
                        customParameters);
            }
           
           
            //poach the coverage store data format
            DataFormat df = new CoverageStoreResource(getContext(),request,response,catalog).createXMLFormat(request, response);
            response.setEntity(df.toRepresentation(info));
            response.setStatus(Status.SUCCESS_CREATED);
        }
        catch( Exception e ) {
            if(e instanceof RestletException) {
                throw (RestletException) e;
            }
            throw new RestletException( "Error auto-configuring coverage", Status.SERVER_ERROR_INTERNAL, e );
        } finally {
            if(reader != null) {
                try {
                    reader.dispose();
                } catch(IOException e)  {
                    // it's ok, we tried
                }           
            }
        }
    }

    private void configureCoverageInfo(CatalogBuilder builder, CoverageStoreInfo storeInfo,
            boolean add, String nativeName, String coverageName, GridCoverage2DReader reader,
            final Map customParameters) throws Exception, IOException {
        CoverageInfo cinfo = builder.buildCoverage( reader, customParameters );
       
        if (coverageName != null) {
            cinfo.setName(coverageName);
        }
        if (nativeName != null) {
            cinfo.setNativeCoverageName(nativeName);
        }
       
        if ( !add ) {
            //update the existing
            String name = coverageName != null ? coverageName: nativeName;
            CoverageInfo existing = catalog.getCoverageByCoverageStore(storeInfo, name);
            if ( existing == null ) {
                //grab the first if there is only one
                List<CoverageInfo> coverages = catalog.getCoveragesByCoverageStore( storeInfo);
                // single coverage reader?
                if ( coverages.size() == 1 && coverages.get(0).getNativeName() == null) {
                    existing = coverages.get(0);
                }
                // check if we have it or not
                if ( coverages.size() == 0 ) {
                    // no coverages yet configured, change add flag and continue on
                    add = true;
                } else {
                    for (CoverageInfo ci : coverages) {
                        if(ci.getNativeName().equals(name)) {
                            existing = ci;
                        }
                    }
                    if(existing == null) {
                        add = true;
                    }
                }
            }
           
            if ( existing != null ) {
                builder.updateCoverage(existing,cinfo);
                catalog.validate(existing, false).throwIfInvalid();
                catalog.save( existing );
                cinfo = existing;
            }
        }
       
        //do some post configuration, if srs is not known or unset, transform to 4326
        if ("UNKNOWN".equals(cinfo.getSRS())) {
            //CoordinateReferenceSystem sourceCRS = cinfo.getBoundingBox().getCoordinateReferenceSystem();
            //CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326", true);
            //ReferencedEnvelope re = cinfo.getBoundingBox().transform(targetCRS, true);
            cinfo.setSRS( "EPSG:4326" );
            //cinfo.setCRS( targetCRS );
            //cinfo.setBoundingBox( re );
        }

        //add/save
        if ( add ) {
            catalog.validate(cinfo, true).throwIfInvalid();
            catalog.add( cinfo );
           
            LayerInfo layerInfo = builder.buildLayer( cinfo );
            //JD: commenting this out, these sorts of edits should be handled
            // with a second PUT request on the created coverage
            /*
            String styleName = form.getFirstValue("style");
            if ( styleName != null ) {
                StyleInfo style = catalog.getStyleByName( styleName );
                if ( style != null ) {
                    layerInfo.setDefaultStyle( style );
                    if ( !layerInfo.getStyles().contains( style ) ) {
                        layerInfo.getStyles().add( style );
                    }
                }
                else {
                    LOGGER.warning( "Client specified style '" + styleName + "'but no such style exists.");
                }
            }

            String path = form.getFirstValue( "path");
            if ( path != null ) {
                layerInfo.setPath( path );
            }
            */

            boolean valid = true;
            try {
                if (!catalog.validate(layerInfo, true).isValid()) {
                    valid = false;
                }
            } catch (Exception e) {
                valid = false;
            }

            layerInfo.setEnabled(valid);
            catalog.add(layerInfo);
        } else {
            catalog.save( cinfo );
        }
    }

    protected File findPrimaryFile(File directory, String format) {
        // first check if the format accepts a whole directory
        if ( ((AbstractGridFormat)coverageFormat).accepts(directory) ) {
            return directory;
        }
        for ( File f : directory.listFiles() ) {
            if(f.isDirectory()){
                File result = findPrimaryFile(f,format);
                if(result!=null){
                    return result;
                }
            }else{
                if ( ((AbstractGridFormat)coverageFormat).accepts(f) ) {
                    return f;
                }
            }
        }
       
        return null;
    }
}
TOP

Related Classes of org.geoserver.catalog.rest.CoverageStoreFileResource

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.