Package com.boundlessgeo.geoserver.api.controllers

Source Code of com.boundlessgeo.geoserver.api.controllers.IconController

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

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

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

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogVisitorAdapter;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.PublishedInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.config.GeoServer;
import org.geoserver.ows.URLMangler.URLType;
import org.geoserver.platform.GeoServerResourceLoader;
import org.geoserver.platform.resource.Paths;
import org.geoserver.platform.resource.Resource;
import org.geoserver.platform.resource.Resource.Type;
import org.geoserver.platform.resource.Resources;
import org.geotools.styling.Style;
import org.geotools.util.KVP;
import org.geotools.util.logging.Logging;
import org.opengis.metadata.citation.OnLineResource;
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.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
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 com.boundlessgeo.geoserver.api.exceptions.NotFoundException;
import com.boundlessgeo.geoserver.json.JSONArr;
import com.boundlessgeo.geoserver.json.JSONObj;
import com.boundlessgeo.geoserver.util.StyleAdaptor;

@Controller
@RequestMapping("/api/icons")
public class IconController extends ApiController {

    static Logger LOG = Logging.getLogger(IconController.class);

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static Map<String,String> ICON_FORMATS = new HashMap<String,String>(
        (Map)new KVP(
            "png","image/png",
            "jpeg","image/jpeg",
            "jpg","image/jpeg",
            "gif","image/gif",
            "svg","image/svg+xml",
            "ttf","application/font-sfnt",
            "properties","text/x-java-properties")
    );
   
    @Autowired
    public IconController(GeoServer geoServer) {
        super(geoServer);
    }
   
    @RequestMapping(value = "/{wsName}", method = RequestMethod.GET)
    public @ResponseBody JSONArr list(@PathVariable String wsName, HttpServletRequest request) throws IOException {

        WorkspaceInfo ws = findWorkspace(wsName, catalog());

        JSONArr arr = new JSONArr();

        Resource styles =  dataDir().get(ws, "styles");
        if (styles.getType() != Type.UNDEFINED) {
            Set<String> usedGraphics = findAllGraphics(ws);

            for(Resource r : styles.list()){
                String name = r.name();
                String ext = fileExt(name);

                if(!ICON_FORMATS.containsKey(ext.toLowerCase())){
                    continue;
                }

                JSONObj item = icon(arr.addObject(), ws, r, request);
                item.put("used", usedGraphics.contains(name));
            }
        }

        return arr;
    }
   

    @RequestMapping(value = "/{wsName}", method = RequestMethod.POST,consumes=MediaType.MULTIPART_FORM_DATA_VALUE)
    public @ResponseStatus(value=HttpStatus.CREATED)
        @ResponseBody JSONArr create(@PathVariable String wsName,  HttpServletRequest request )
        throws IOException, FileUploadException {

        WorkspaceInfo ws = findWorkspace(wsName, catalog());
       
        // Resource resource = dataDir().get(ws).get("icons"); // GEOS-6690
        GeoServerResourceLoader rl = geoServer.getCatalog().getResourceLoader();       
        Resource styles = rl.get(Paths.path("workspaces",ws.getName(),"styles"));

        ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
        @SuppressWarnings("unchecked")
        List<FileItem> input = (List<FileItem>) upload.parseRequest(request);

        JSONArr created = new JSONArr();
        for (FileItem file : input) {
            String filename = file.getName();

            // trim filename if required
            if (filename.lastIndexOf('/') != -1) {
                filename = filename.substring(filename.lastIndexOf('/'));
            }
            if (filename.lastIndexOf('\\') != -1) {
                filename = filename.substring(filename.lastIndexOf('\\'));
            }
            String ext = fileExt(filename);
            if( !ICON_FORMATS.containsKey(ext)){
                String msg = "Icon "+filename+" format "+ext+" unsupported - try:"+ICON_FORMATS.keySet();
                LOG.warning(msg);
                throw new FileUploadException(msg);
            }
            try {
                InputStream data = file.getInputStream();               
                Resources.copy(data, styles, filename);

                icon(created.addObject(), ws, styles.get(filename), request);
            } catch (Exception e) {
                throw new FileUploadException("Unable to write "+filename,e);
            }
        }

        return created;
    }
   

    JSONObj icon(JSONObj obj, WorkspaceInfo ws, Resource r, HttpServletRequest req) {
        String filename = r.name();
        String ext = fileExt(filename);
        Object format = ICON_FORMATS.get(ext.toLowerCase());
       
        obj.put("name", filename)
            .put("format",ext)
            .put("mime",format)
            .put("url", IO.url( req,  "/icons/%s/%s", ws.getName(),filename ));

        IO.date(obj.putObject("modified"), new Date(r.lastmodified()));
        return obj;
    }

    @RequestMapping(value = "/{wsName}/{icon:.+}", method = RequestMethod.GET)
    public @ResponseBody byte[] raw(@PathVariable String wsName, @PathVariable String icon,
                                   HttpServletResponse response) throws IOException {

        WorkspaceInfo ws = findWorkspace(wsName, catalog());

        GeoServerResourceLoader rl = geoServer.getCatalog().getResourceLoader();
        Resource resource = rl.get(Paths.path("workspaces",ws.getName(),"styles",icon));

        if( resource.getType() != Type.RESOURCE ){
            throw new NotFoundException("Icon "+icon+" not found");
        }
        String ext = fileExt(icon);
        if( !ICON_FORMATS.containsKey(ext)){
            throw new NotFoundException("Icon "+icon+" format unsupported");
        }
        String mimeType = ICON_FORMATS.get(ext.toLowerCase());

        response.setContentType(mimeType);
        //response.setStatus(HttpServletResponse.SC_OK);
        response.setDateHeader("Last-Modified", resource.lastmodified() );
        //IOUtils.copy(resource.in(), response.getOutputStream());

        try (
            InputStream in = resource.in();
        ) {
            return IOUtils.toByteArray(in);
        }
    }

    @RequestMapping(value = "/{wsName}/{icon:.+}", method = RequestMethod.DELETE)
    public boolean delete(@PathVariable String wsName, @PathVariable String icon) throws IOException {

        WorkspaceInfo ws = findWorkspace(wsName, catalog());

        GeoServerResourceLoader rl = geoServer.getCatalog().getResourceLoader();
        Resource resource = rl.get(Paths.path("workspaces",ws.getName(),"styles",icon));
        if( resource.getType() != Type.RESOURCE ){
            throw new NotFoundException("Icon "+icon+" not found");
        }
        String ext = fileExt(icon);
        if( !ICON_FORMATS.containsKey(ext)){
            throw new NotFoundException("Icon "+icon+" format unsupported");
        }
        return resource.delete();
    }
   
    @ExceptionHandler(FileUploadException.class)
    public @ResponseBody JSONObj error(FileUploadException e, HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        return IO.error(new JSONObj(), e );
    }
    @ExceptionHandler(IllegalArgumentException.class)
    public @ResponseBody JSONObj error(IllegalArgumentException e, HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        return IO.error(new JSONObj(), e );
    }
   

    /**
     * Check what icons/fonts are referenced style.
     * @return Set of icons used by layer.
     * @throws IOException Trouble access default style
     */   
    @SuppressWarnings("unchecked")
    private Set<String> findAllGraphics(WorkspaceInfo ws) throws IOException {
        final Catalog cat = geoServer.getCatalog();

        final Set<String> externalGraphics = new HashSet<String>();
       
        ws.accept( new CatalogVisitorAdapter() {
            @Override
            public void visit(WorkspaceInfo workspace) {
                for( StoreInfo store : cat.getStoresByWorkspace(workspace,StoreInfo.class)){
                    try {
                        store.accept(this);
                    }
                    catch( Throwable t){
                        LOG.log(Level.FINE,String.format("Trouble checking store %s for icon use:%s", store.getName(),t));
                    }
                }
                for( LayerGroupInfo map : cat.getLayerGroupsByWorkspace(workspace)){
                    try {
                        map.accept(this);
                    }
                    catch( Throwable t){
                        LOG.log(Level.FINE,String.format("Trouble checking map %s for icon use:%s", map.getName(),t));
                    }   
                }
            }
            @Override
            public void visit(LayerGroupInfo layerGroup) {
                for( PublishedInfo child : layerGroup.getLayers() ){
                    try {
                        child.accept(this);
                    }
                    catch( Throwable t){
                        LOG.log(Level.FINE,String.format("Trouble checking layer %s for icon use:%s", child.getName(),t));
                    }
                }
            }
            @Override
            public void visit(LayerInfo layer) {
                StyleInfo style = layer.getDefaultStyle();
                if( style != null ){
                    try {
                        style.accept(this);
                    }
                    catch( Throwable t ){
                        LOG.log(Level.FINE,String.format("Trouble checking layer %s for icon use:%s", layer.getName(),t));
                    }
                }
                else {
                    LOG.fine(String.format("Layer %s has no default style", layer.getName()));
                }
            }
            @Override
            public void visit(StyleInfo s) {
                Style style = null;
                try {
                    style = s.getStyle();
                } catch (IOException e) {
                    LOG.log(Level.FINE,"Unable to access style "+s.getName()+":"+e,e);
                }       
                if( style != null ){
                    style.accept(new StyleAdaptor() {
                        public Object visit(OnLineResource resource, Object data) {
                            try {
                                URI uri = resource.getLinkage();
                                if (uri != null) {
                                    String path = uri.toString();
                                    if( path != null ){
                                        if( path.lastIndexOf('/') != -1 ){
                                            path = path.substring(path.lastIndexOf('/')+1);
                                        }
                                        ((Set<String>) data).add(path);
                                    }
                                }
                            }
                            catch( Throwable t){
                                LOG.log(Level.FINE,String.format("Trouble OnLineResource %s for icon use:%s", resource,t));
                            }
                            return data;
                        }
                    }, externalGraphics);
                }
            }
        });
        return externalGraphics;
    }

    String fileExt(String filename) {
        return FilenameUtils.getExtension(filename.toLowerCase());
    }
}
TOP

Related Classes of com.boundlessgeo.geoserver.api.controllers.IconController

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.