Package org.geoserver.importer.rest

Source Code of org.geoserver.importer.rest.DirectoryResource$DirectoryJSONFormat

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

import static org.restlet.data.MediaType.APPLICATION_GNU_TAR;
import static org.restlet.data.MediaType.APPLICATION_GNU_ZIP;
import static org.restlet.data.MediaType.APPLICATION_TAR;
import static org.restlet.data.MediaType.APPLICATION_ZIP;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

import net.sf.json.JSONObject;

import org.geoserver.rest.RestletException;
import org.geoserver.rest.format.DataFormat;
import org.geoserver.rest.format.StreamDataFormat;
import org.geoserver.importer.Directory;
import org.geoserver.importer.FileData;
import org.geoserver.importer.ImportContext;
import org.geoserver.importer.Importer;
import org.geoserver.importer.SpatialFile;
import org.geoserver.importer.mosaic.Granule;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;

public class DirectoryResource extends BaseResource {

    static Map<MediaType,String> ARCHIVE_MIME_TYPES = new HashMap<MediaType,String>();
    {
        ARCHIVE_MIME_TYPES.put(APPLICATION_ZIP, "zip");
        ARCHIVE_MIME_TYPES.put(APPLICATION_GNU_ZIP, "gz");
        ARCHIVE_MIME_TYPES.put(APPLICATION_TAR, ".tar");
   
        //GNU_TAR doesn't mean gzipped tarball but we'll hack for now
        ARCHIVE_MIME_TYPES.put(APPLICATION_GNU_TAR, ".tar.gz");
    }

    public DirectoryResource(Importer importer) {
        super(importer);
    }

    @Override
    protected List<DataFormat> createSupportedFormats(Request request, Response response) {
        return (List) Arrays.asList(new DirectoryJSONFormat(MediaType.APPLICATION_JSON),
                new DirectoryJSONFormat(MediaType.TEXT_HTML));
    }

    @Override
    public void handleGet() {
        Directory dir = lookupDirectory();
        Object response = dir;

        if (getAttribute("file") != null) {
            response = lookupFile(dir);
        }

        DataFormat formatGet = getFormatGet();
        if (formatGet == null) {
            formatGet = new DirectoryJSONFormat(MediaType.APPLICATION_JSON);
        }

        getResponse().setEntity(formatGet.toRepresentation(response));
    }

    @Override
    public boolean allowPost() {
        return getAttribute("file") == null;
    }

    @Override
    public void handlePost() {
        MediaType mimeType = getRequest().getEntity().getMediaType();
        if (ARCHIVE_MIME_TYPES.containsKey(mimeType)) {
            try {
                handleFileUpload(mimeType);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        else {
            throw new RestletException("Unsupported POST", Status.CLIENT_ERROR_FORBIDDEN);
        }
    }

    void handleFileUpload(MediaType mimeType) throws IOException {
        File tmp = File.createTempFile("upload", "tmp");
        tmp.delete();

        String ext = ARCHIVE_MIME_TYPES.get(mimeType);
       
        Directory dir = lookupDirectory();
        dir.accept(tmp.getName() + "." + ext, getRequest().getEntity().getStream());
        dir.prepare();
    }

    @Override
    public boolean allowPut() {
        return getAttribute("file") != null;
    }

    @Override
    public void handlePut() {
        //TODO: this only handles granule timestamps at the moment, expand to handle more
        JSONObject obj = (JSONObject) getFormatPostOrPut().toObject(getRequest().getEntity());
        FileData file = lookupFile();
        if (file instanceof SpatialFile) {
            SpatialFile sf = (SpatialFile) file;
            if (sf instanceof Granule) {
                Granule g = (Granule) sf;
                if (obj.has("timestamp")) {
                    String ts = obj.getString("timestamp");
                    try {
                        g.setTimestamp(ImportJSONWriter.DATE_FORMAT.parse(ts));
                    } catch (ParseException e) {
                        throw new RestletException("Could not parse timestamp: " + ts + ", must be "
                            + "format: " + ImportJSONWriter.DATE_FORMAT.toPattern(),
                            Status.CLIENT_ERROR_BAD_REQUEST);
                    }

                    getResponse().setEntity(getFormatGet().toRepresentation(g));
                }
            }
        }

        getResponse().setStatus(Status.SUCCESS_OK);
    }

    public boolean allowDelete() {
        return allowPut();
    }

    public void handleDelete() {
        Directory dir = lookupDirectory();
        FileData file = lookupFile();

        if (dir.getFiles().remove(file)) {
            getResponse().setStatus(Status.SUCCESS_NO_CONTENT);
        }
        else {
            throw new RestletException("Unable to remove file: " + file.getName(),
                Status.CLIENT_ERROR_BAD_REQUEST);
        }

    };

    Directory lookupDirectory() {
        ImportContext context = context();
        if (!(context.getData() instanceof Directory)) {
            throw new RestletException("Data is not a directory", Status.CLIENT_ERROR_BAD_REQUEST);   
        }

        return (Directory) context.getData();
    }

    FileData lookupFile() {
        return lookupFile(lookupDirectory());
    }

    FileData lookupFile(Directory dir ) {
        final String file = getAttribute("file");
        try {
            if (file != null) {
                return Iterators.find(dir.getFiles().iterator(), new Predicate<FileData>() {
                    @Override
                    public boolean apply(FileData input) {
                        return input.getFile().getName().equals(file);
                    }
                });
            }
        }
        catch(NoSuchElementException e) {
           
        }
        throw new RestletException("No such file: " + file, Status.CLIENT_ERROR_NOT_FOUND);
    }

    class DirectoryJSONFormat extends StreamDataFormat {

        protected DirectoryJSONFormat(MediaType type) {
            super(type);
        }

        @Override
        protected Object read(InputStream in) throws IOException {
            return newReader(in).object();
        }

        @Override
        protected void write(Object object, OutputStream out) throws IOException {
            ImportJSONWriter io = newWriter(out);

            Object parent = task(true);
            if (parent == null) {
                parent = context();
            }

            if (object instanceof Directory) {
                Directory d = (Directory) object;
                String path = getRequest().getResourceRef().getPath();
                if (path.matches(".*/files/?")) {
                    io.files(d, parent, true, expand(1));
                }
                else {
                    io.directory(d, parent, expand(1));
                }
            }
            else {
                io.file((FileData)object, parent, expand(1), true);
            }
        }
    }
}
TOP

Related Classes of org.geoserver.importer.rest.DirectoryResource$DirectoryJSONFormat

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.