/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved. * This code is licensed under the GPL 2.0 license, availible at the root * application directory. */ package org.vfny.geoserver.wms.responses; import org.geoserver.config.GeoServer; import org.geoserver.config.ServiceInfo; import org.geoserver.platform.ServiceException; import org.vfny.geoserver.Request; import org.vfny.geoserver.Response; import org.vfny.geoserver.wms.WmsException; import org.vfny.geoserver.wms.requests.GetFeatureInfoRequest; import org.vfny.geoserver.wms.responses.featureInfo.GetFeatureInfoDelegate; import org.vfny.geoserver.wms.responses.featureInfo.GmlFeatureInfoResponse; import org.vfny.geoserver.wms.responses.featureInfo.HTMLTableFeatureInfoResponse; import org.vfny.geoserver.wms.responses.featureInfo.TextFeatureInfoResponse; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * A GetFeatureInfoResponse object is responsible for generating GetFeatureInfo * content in the format specified. The way the content is generated is * independent of this class, wich will use a delegate object based on the * output format requested * * @author Gabriel Roldan, Axios Engineering * @version $Id$ */ public class GetFeatureInfoResponse implements Response { /** package logger */ private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger(GetMapResponse.class.getPackage().getName()); /** list of output format specialists */ private static final List delegates = new LinkedList(); /** * The list of all the supported output formats */ private static final List supportedMimeTypes = new LinkedList(); static { GetFeatureInfoDelegate producer; producer = new TextFeatureInfoResponse(); supportedMimeTypes.addAll(producer.getSupportedFormats()); delegates.add(producer); producer = new HTMLTableFeatureInfoResponse(); supportedMimeTypes.addAll(producer.getSupportedFormats()); delegates.add(producer); producer = new GmlFeatureInfoResponse(); supportedMimeTypes.addAll(producer.getSupportedFormats()); delegates.add(producer); } /** * A delegate specialized in producing the required output format. */ private GetFeatureInfoDelegate delegate; /** * Creates a new GetMapResponse object. */ public GetFeatureInfoResponse() { } /** * Returns any extra headers that this service might want to set in the HTTP response object. * @see org.vfny.geoserver.Response#getResponseHeaders() */ public HashMap getResponseHeaders() { return null; } /** * Obtains a <code>GetFeatureInfoDelegate</code> for the requested output format, * and tells it to execute the request. * * @param request DOCUMENT ME! * * @throws ServiceException DOCUMENT ME! */ public void execute(Request request) throws ServiceException { LOGGER.entering(getClass().getName(), "execute", new Object[] { request }); GetFeatureInfoRequest getFeatureInfoReq = (GetFeatureInfoRequest) request; this.delegate = getDelegate(getFeatureInfoReq); delegate.execute(request); } /** * Asks the internal GetFeatureInfoDelegate for the MIME type of the result that it * will generate or is ready to, and returns it * * @param gs the global app context * * @return the MIME type of the map generated or ready to generate * * @throws IllegalStateException if a GetMapDelegate is not setted yet * @see Response#getContentType(GeoServer) */ public String getContentType(GeoServer gs) throws IllegalStateException { if (delegate == null) { throw new IllegalStateException("No request has been proceced"); } return delegate.getContentType(gs); } /** * Returns the content encoding of the internal delegate * * @return <code>null</code> since no content encoding (such as GZIP) is * done. * * @throws IllegalStateException if this method is called before processing * a request (i.e., execute() has not been called) */ public String getContentEncoding() { if (delegate == null) { throw new IllegalStateException("No request has been proceced"); } return delegate.getContentEncoding(); } /** * if a GetFeatureInfoDelegate is set, calls it's abort method. Elsewere do * nothing. * * @see Response#abort(ServiceInfo) */ public void abort(ServiceInfo gs) { if (delegate != null) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("asking delegate for aborting the process"); } delegate.abort(gs); } } /** * delegates the writing and encoding of the results of the request to the * <code>GetMapDelegate</code> wich is actually processing it, and has * been obtained when <code>execute(Request)</code> was called * * @param out the output to where the map must be written * * @throws ServiceException if the delegate throws a ServiceException * inside its <code>writeTo(OuptutStream)</code>, mostly due to * @throws IOException if the delegate throws an IOException inside its * <code>writeTo(OuptutStream)</code>, mostly due to * @throws IllegalStateException if this method is called before * <code>execute(Request)</code> has succeed */ public void writeTo(OutputStream out) throws ServiceException, IOException { if (delegate == null) { throw new IllegalStateException( "No GetMapDelegate is setted, make sure you have called execute and it has succeed"); } if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer(new StringBuffer("asking delegate for write to ").append(out).toString()); } delegate.writeTo(out); } /** * Creates a GetMapDelegate specialized in generating the requested map * format * * @param request a request parameter object wich holds the processed * request objects, such as layers, bbox, outpu format, etc. * * @return A specialization of <code>GetMapDelegate</code> wich can produce * the requested output map format * * @throws WmsException if no specialization is configured for the output * format specified in <code>request</code> or if it can't be * instantiated */ private static GetFeatureInfoDelegate getDelegate(GetFeatureInfoRequest request) throws WmsException { String requestFormat = request.getInfoFormat(); if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer(new StringBuffer("request format is ").append(requestFormat).toString()); } GetFeatureInfoDelegate curDelegate = null; Class delegateClass = null; for (Iterator it = delegates.iterator(); it.hasNext();) { curDelegate = (GetFeatureInfoDelegate) it.next(); if (curDelegate.canProduce(requestFormat)) { delegateClass = curDelegate.getClass(); if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer(new StringBuffer("found GetFeatureInfoDelegate ").append( delegateClass).toString()); } break; } } if (delegateClass == null) { // let's default to something sensible. If the parameter is empty we return a // TextFeatureInfoResponse, so let's do the same thing here. See the "hack" comment in // GetFeatureInfoKVPReader.java. delegateClass = new TextFeatureInfoResponse().getClass(); } try { curDelegate = (GetFeatureInfoDelegate) delegateClass.newInstance(); } catch (Exception ex) { throw new WmsException(ex, "Cannot obtain the map generator for the requested format", "GetMapResponse::getDelegate()"); } return curDelegate; } /** * iterates over the registered Map producers and fills a list with all the * map formats' MIME types that the producers can handle * * @return DOCUMENT ME! */ public static List getFormats() { return supportedMimeTypes; } /* (non-Javadoc) * @see org.vfny.geoserver.Response#getContentDisposition() */ public String getContentDisposition() { // TODO Auto-generated method stub return null; } }