/* (c) 2014 - 2015 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.kml.icons; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.StyleInfo; import org.geoserver.ows.util.KvpUtils; import org.geotools.styling.Style; import org.geotools.util.logging.Logging; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; /** * Custom servlet/controller for rendering KML icons. */ public class IconService extends AbstractController { static Logger LOG = Logging.getLogger(IconService.class); static Pattern URI = Pattern.compile("/icon/(?:([^/]+)/)?([^/]+)/?"); private final Catalog catalog; public IconService(Catalog catalog) { this.catalog = catalog; } @Override protected ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception { String path = request.getPathInfo(); Matcher m = URI.matcher(path); if (!m.matches()) { response.sendError(400, "Bad request, path must be of form: /icons/[<workspace>/]<style>"); return null; } String workspace = null, styleName = null; if (m.groupCount() == 2) { workspace = m.group(1); styleName = m.group(2); } else { styleName = m.group(1); } StyleInfo styleInfo = workspace != null ? catalog.getStyleByName(workspace, styleName) : catalog.getStyleByName(styleName); if (styleInfo == null) { String msg = "No such style " + styleName; if (workspace != null) { msg += " in workspace " + workspace; } response.sendError(404, msg); return null; } String q = request.getQueryString(); try { Style style = styleInfo.getStyle(); Map<String,Object> properties = q != null ? KvpUtils.parseQueryString("?"+q) : Collections.EMPTY_MAP; Map<String, String> kvp = new HashMap<String, String>(); for (String key : properties.keySet()) { Object value = properties.get(key); if (value instanceof String) { kvp.put(key, (String) value); } else { String[] values = (String[]) value; kvp.put(key, values[0]); } } Style adjustedStyle = IconPropertyInjector.injectProperties(style, kvp); BufferedImage image = IconRenderer.renderIcon(adjustedStyle); response.setContentType("image/png"); ImageIO.write(image, "PNG", response.getOutputStream()); response.getOutputStream().flush(); } catch (IOException e) { String msg = "Failed to load style: " + workspace + " " + styleName; response.sendError(500, msg + ", " + e.getMessage()); LOG.log(Level.WARNING, msg, e); } return null; } }