/* (c) 2017 Open Source Geospatial Foundation - all rights reserved * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.opensearch.eo.response; import static org.geoserver.ows.util.ResponseUtils.baseURL; import static org.geoserver.ows.util.ResponseUtils.buildURL; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import org.geoserver.config.GeoServerInfo; import org.geoserver.ows.Request; import org.geoserver.ows.URLMangler.URLType; import org.geoserver.ows.util.OwsUtils; import org.geoserver.ows.util.ResponseUtils; import org.geoserver.platform.ServiceException; import org.geotools.xml.transform.Translator; import org.xml.sax.ContentHandler; /** * Based on the indications at http://www.opensearch.org/Documentation/Developer_how_to_guide#How_to_indicate_errors encodes the exception into a RSS * document, e.g. * * <pre> * {@code * <rss version="2.0" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/"> <channel> <title>title</title> <link>link</link> <description>description</description> <openSearch:totalResults>1</openSearch:totalResults> <openSearch:startIndex>1</openSearch:startIndex> <openSearch:itemsPerPage>1</openSearch:itemsPerPage> <item> <title>Error</title> <description>error message</description> </item> </channel> } * </pre> * * @author Andrea Aime - GeoSolutions */ public class RSSExceptionTransformer extends LambdaTransformerBase { Request request; GeoServerInfo geoServer; public RSSExceptionTransformer(GeoServerInfo geoServer, Request request) { this.request = request; this.geoServer = geoServer; } @Override public Translator createTranslator(ContentHandler handler) { return new ExceptionTranslator(handler); } public static String getDescription(GeoServerInfo geoServer, ServiceException e) { StringBuffer sb = new StringBuffer(); OwsUtils.dumpExceptionMessages(e, sb, true); if (geoServer.getSettings().isVerboseExceptions()) { ByteArrayOutputStream stackTrace = new ByteArrayOutputStream(); e.printStackTrace(new PrintStream(stackTrace)); sb.append("\nDetails:\n"); sb.append(ResponseUtils.encodeXML(new String(stackTrace.toByteArray()))); } return sb.toString(); } class ExceptionTranslator extends LambdaTranslatorSupport { public ExceptionTranslator(ContentHandler contentHandler) { super(contentHandler); } @Override public void encode(Object o) throws IllegalArgumentException { ServiceException e = (ServiceException) o; element("rss", () -> channel(e), // attributes("xmlns:opensearch", "http://a9.com/-/spec/opensearch/1.1/")); } private void channel(ServiceException e) { element("channel", () -> { element("title", "OpenSearch for EO Error report"); element("link", buildSelfUrl()); element("opensearch:totalResults", "1"); element("opensearch:startIndex", "1"); element("opensearch:itemsPerPage", "1"); element("item", () -> itemContents(e)); }); } private void itemContents(ServiceException e) { element("title", e.getMessage()); element("description", getDescription(geoServer, e)); } private String buildSelfUrl() { String baseURL = baseURL(request.getHttpRequest()); return buildURL(baseURL, "oseo/description", null, URLType.SERVICE); } } }