com.boundlessgeo.geoserver.api.controllers.WorkspaceController.java Source code

Java tutorial

Introduction

Here is the source code for com.boundlessgeo.geoserver.api.controllers.WorkspaceController.java

Source

/* (c) 2014 - 2015 Boundless, http://boundlessgeo.com
 * This code is licensed under the GPL 2.0 license.
 */
package com.boundlessgeo.geoserver.api.controllers;

import com.boundlessgeo.geoserver.api.exceptions.BadRequestException;
import com.boundlessgeo.geoserver.json.JSONArr;
import com.boundlessgeo.geoserver.json.JSONObj;
import com.boundlessgeo.geoserver.util.RecentObjectCache;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.io.FileUtils;
import org.geoserver.catalog.CascadeDeleteVisitor;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.catalog.Predicates;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.util.CloseableIterator;
import org.geoserver.config.GeoServer;
import org.geoserver.data.util.IOUtils;

import com.boundlessgeo.geoserver.bundle.BundleExporter;
import com.boundlessgeo.geoserver.bundle.BundleImporter;
import com.boundlessgeo.geoserver.bundle.ExportOpts;
import com.boundlessgeo.geoserver.bundle.ImportOpts;

import org.geoserver.platform.resource.Resource;
import org.geoserver.platform.resource.Resource.Type;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

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

import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Date;

@Controller
@RequestMapping("/api/workspaces")
public class WorkspaceController extends ApiController {

    public static final String APPLICATION_ZIP_VALUE = "application/zip";

    @Autowired
    public WorkspaceController(GeoServer geoServer, RecentObjectCache recentCache) {
        super(geoServer, recentCache);
    }

    @RequestMapping(method = RequestMethod.GET)
    public @ResponseBody JSONArr list() {
        JSONArr arr = new JSONArr();

        Catalog cat = geoServer.getCatalog();

        WorkspaceInfo def = cat.getDefaultWorkspace();
        if (def != null) {
            workspace(arr.addObject(), def, namespaceFor(def), true);
        }

        try (CloseableIterator<WorkspaceInfo> list = cat.list(WorkspaceInfo.class, Predicates.acceptAll());) {
            while (list.hasNext()) {
                WorkspaceInfo ws = list.next();
                if (def != null && ws.getName().equals(def.getName())) {
                    continue;
                }

                NamespaceInfo ns = namespaceFor(ws);
                workspace(arr.addObject(), ws, ns, false);
            }
        }

        return arr;
    }

    @RequestMapping(value = "/recent", method = RequestMethod.GET)
    public @ResponseBody JSONArr recent() {
        Catalog cat = catalog();

        JSONArr arr = new JSONArr();

        for (RecentObjectCache.Ref ref : recent.list(WorkspaceInfo.class)) {
            WorkspaceInfo ws = cat.getWorkspaceByName(ref.name);
            if (ws != null) {
                NamespaceInfo ns = cat.getNamespaceByPrefix(ref.name);
                workspace(arr.addObject(), ws, ns, false);
            }
        }
        return arr;
    }

    @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(HttpStatus.CREATED)
    public @ResponseBody JSONObj create(@RequestBody JSONObj obj) {
        Catalog cat = geoServer.getCatalog();

        String wsName = obj.str("name");
        if (wsName == null) {
            throw new BadRequestException("Workspace must have a name");
        }

        String nsUri = obj.str("uri");
        if (nsUri == null) {
            nsUri = "http://" + wsName;
        }

        boolean isDefault = obj.has("default") ? obj.bool("default") : false;

        WorkspaceInfo ws = cat.getFactory().createWorkspace();
        ws.setName(wsName);

        NamespaceInfo ns = cat.getFactory().createNamespace();
        ns.setPrefix(wsName);
        ns.setURI(nsUri);

        Metadata.created(ws, new Date());

        cat.add(ws);
        cat.add(ns);
        recent.add(WorkspaceInfo.class, ws);

        if (isDefault) {
            cat.setDefaultWorkspace(ws);
            cat.setDefaultNamespace(ns);
        }

        return workspace(new JSONObj(), ws, ns, isDefault);
    }

    @RequestMapping(value = "/{wsName:.+}", method = RequestMethod.GET)
    public @ResponseBody JSONObj get(@PathVariable String wsName) {
        Catalog cat = geoServer.getCatalog();

        WorkspaceInfo ws = findWorkspace(wsName, cat);
        WorkspaceInfo def = cat.getDefaultWorkspace();

        JSONObj obj = IO.workspace(new JSONObj(), ws, namespaceFor(ws), def != null && def.equals(ws));

        obj.put("maps", countMaps(ws, cat));
        obj.put("layers", countLayers(ws, cat));
        obj.put("stores", countStores(ws, cat));

        return obj;
    }

    JSONObj workspace(JSONObj obj, WorkspaceInfo ws, NamespaceInfo ns, boolean isDefault) {
        IO.workspace(obj, ws, ns, isDefault);
        if (!obj.has(Metadata.MODIFIED)) {
            // derive from resource
            Resource r = dataDir().config(ws);
            if (r.getType() != Type.UNDEFINED) {
                IO.date(obj.putObject("modified"), new Date(r.lastmodified()));
            }
        }
        return obj;
    }

    Integer countMaps(WorkspaceInfo ws, Catalog cat) {
        return cat.count(LayerGroupInfo.class, Predicates.equal("workspace.name", ws.getName()));
    }

    Integer countLayers(WorkspaceInfo ws, Catalog cat) {
        return cat.count(LayerInfo.class, Predicates.equal("resource.namespace.prefix", ws.getName()));
    }

    Integer countStores(WorkspaceInfo ws, Catalog cat) {
        return cat.count(StoreInfo.class, Predicates.equal("workspace.name", ws.getName()));
    }

    @RequestMapping(value = "/{wsName:.+}", method = RequestMethod.PATCH)
    public @ResponseBody JSONObj patch(@PathVariable String wsName, @RequestBody JSONObj obj) {
        return put(wsName, obj);
    }

    @RequestMapping(value = "/{wsName:.+}", method = RequestMethod.PUT)
    public @ResponseBody JSONObj put(@PathVariable String wsName, @RequestBody JSONObj obj) {
        Catalog cat = geoServer.getCatalog();

        WorkspaceInfo ws = findWorkspace(wsName, cat);
        NamespaceInfo ns = namespaceFor(ws);

        String name = obj.str("name");
        if (name != null) {
            ws.setName(name);
            ns.setPrefix(name);
        }

        String uri = obj.str("uri");
        if (uri != null) {
            ns.setURI(uri);
        }
        Metadata.modified(ws, new Date());
        cat.save(ws);
        cat.save(ns);
        recent.add(WorkspaceInfo.class, ws);

        Boolean isDefault = obj.bool("default");
        if (Boolean.TRUE.equals(isDefault)) {
            cat.setDefaultWorkspace(ws);
            cat.setDefaultNamespace(ns);
        } else if (Boolean.FALSE.equals(isDefault)) {
            WorkspaceInfo defaultWorkspace = cat.getDefaultWorkspace();
            if (defaultWorkspace != null && defaultWorkspace.getId().equals(ws.getId())) {
                cat.setDefaultWorkspace(null);
                cat.setDefaultNamespace(null);
            }
        }
        return IO.workspace(new JSONObj(), ws, ns, isDefault == Boolean.TRUE);
    }

    @RequestMapping(value = "/{wsName:.+}", method = RequestMethod.DELETE)
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    public void delete(@PathVariable String wsName, HttpServletResponse response) {
        Catalog cat = geoServer.getCatalog();

        WorkspaceInfo ws = findWorkspace(wsName, cat);
        new CascadeDeleteVisitor(cat).visit(ws);

        recent.remove(WorkspaceInfo.class, ws);
    }

    @RequestMapping(value = "/{wsName}/export", method = RequestMethod.POST, produces = APPLICATION_ZIP_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public void export(@PathVariable String wsName, HttpServletResponse response) throws Exception {
        Catalog cat = geoServer.getCatalog();

        WorkspaceInfo ws = findWorkspace(wsName, cat);
        BundleExporter exporter = new BundleExporter(cat, new ExportOpts(ws));
        exporter.run();

        Path zip = exporter.zip();

        response.setContentType(APPLICATION_ZIP_VALUE);
        response.setHeader("Content-Disposition", "attachment; filename=\"" + zip.getFileName() + "\"");
        FileUtils.copyFile(zip.toFile(), response.getOutputStream());
    }

    @RequestMapping(value = "/{wsName}/import", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public void inport(@PathVariable String wsName, HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        Catalog cat = geoServer.getCatalog();

        WorkspaceInfo ws = findWorkspace(wsName, cat);

        // grab the uploaded file
        FileItemIterator files = doFileUpload(request);
        if (!files.hasNext()) {
            throw new BadRequestException("Request must contain a single file");
        }
        Path zip = Files.createTempFile(null, null);
        FileItemStream item = files.next();
        try (InputStream stream = item.openStream()) {
            IOUtils.copy(stream, zip.toFile());
        }
        BundleImporter importer = new BundleImporter(cat, new ImportOpts(ws));
        importer.unzip(zip);
        importer.run();
    }

}