001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.vfny.geoserver.wms.responses;
006:
007: import org.vfny.geoserver.Request;
008: import org.vfny.geoserver.Response;
009: import org.vfny.geoserver.ServiceException;
010: import org.vfny.geoserver.global.GeoServer;
011: import org.vfny.geoserver.global.Service;
012: import org.vfny.geoserver.wms.WmsException;
013: import org.vfny.geoserver.wms.requests.GetFeatureInfoRequest;
014: import org.vfny.geoserver.wms.responses.featureInfo.GetFeatureInfoDelegate;
015: import org.vfny.geoserver.wms.responses.featureInfo.GmlFeatureInfoResponse;
016: import org.vfny.geoserver.wms.responses.featureInfo.HTMLTableFeatureInfoResponse;
017: import org.vfny.geoserver.wms.responses.featureInfo.TextFeatureInfoResponse;
018: import java.io.IOException;
019: import java.io.OutputStream;
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.LinkedList;
023: import java.util.List;
024: import java.util.logging.Level;
025: import java.util.logging.Logger;
026:
027: /**
028: * A GetFeatureInfoResponse object is responsible for generating GetFeatureInfo
029: * content in the format specified. The way the content is generated is
030: * independent of this class, wich will use a delegate object based on the
031: * output format requested
032: *
033: * @author Gabriel Roldan, Axios Engineering
034: * @version $Id: GetFeatureInfoResponse.java 7746 2007-11-13 15:38:35Z aaime $
035: */
036: public class GetFeatureInfoResponse implements Response {
037: /** package logger */
038: private static final Logger LOGGER = org.geotools.util.logging.Logging
039: .getLogger(GetMapResponse.class.getPackage().getName());
040:
041: /** list of output format specialists */
042: private static final List delegates = new LinkedList();
043:
044: /**
045: * The list of all the supported output formats
046: */
047: private static final List supportedMimeTypes = new LinkedList();
048:
049: static {
050: GetFeatureInfoDelegate producer;
051:
052: producer = new TextFeatureInfoResponse();
053: supportedMimeTypes.addAll(producer.getSupportedFormats());
054: delegates.add(producer);
055:
056: producer = new HTMLTableFeatureInfoResponse();
057: supportedMimeTypes.addAll(producer.getSupportedFormats());
058: delegates.add(producer);
059:
060: producer = new GmlFeatureInfoResponse();
061: supportedMimeTypes.addAll(producer.getSupportedFormats());
062: delegates.add(producer);
063: }
064:
065: /**
066: * A delegate specialized in producing the required output format.
067: */
068: private GetFeatureInfoDelegate delegate;
069:
070: /**
071: * Creates a new GetMapResponse object.
072: */
073: public GetFeatureInfoResponse() {
074: }
075:
076: /**
077: * Returns any extra headers that this service might want to set in the HTTP response object.
078: * @see org.vfny.geoserver.Response#getResponseHeaders()
079: */
080: public HashMap getResponseHeaders() {
081: return null;
082: }
083:
084: /**
085: * Obtains a <code>GetFeatureInfoDelegate</code> for the requested output format,
086: * and tells it to execute the request.
087: *
088: * @param request DOCUMENT ME!
089: *
090: * @throws ServiceException DOCUMENT ME!
091: */
092: public void execute(Request request) throws ServiceException {
093: LOGGER.entering(getClass().getName(), "execute",
094: new Object[] { request });
095:
096: GetFeatureInfoRequest getFeatureInfoReq = (GetFeatureInfoRequest) request;
097: this .delegate = getDelegate(getFeatureInfoReq);
098: delegate.execute(request);
099: }
100:
101: /**
102: * Asks the internal GetFeatureInfoDelegate for the MIME type of the result that it
103: * will generate or is ready to, and returns it
104: *
105: * @param gs the global app context
106: *
107: * @return the MIME type of the map generated or ready to generate
108: *
109: * @throws IllegalStateException if a GetMapDelegate is not setted yet
110: */
111: public String getContentType(GeoServer gs)
112: throws IllegalStateException {
113: if (delegate == null) {
114: throw new IllegalStateException(
115: "No request has been proceced");
116: }
117:
118: return delegate.getContentType(gs);
119: }
120:
121: /**
122: * Returns the content encoding of the internal delegate
123: *
124: * @return <code>null</code> since no content encoding (such as GZIP) is
125: * done.
126: *
127: * @throws IllegalStateException if this method is called before processing
128: * a request (i.e., execute() has not been called)
129: */
130: public String getContentEncoding() {
131: if (delegate == null) {
132: throw new IllegalStateException(
133: "No request has been proceced");
134: }
135:
136: return delegate.getContentEncoding();
137: }
138:
139: /**
140: * if a GetFeatureInfoDelegate is set, calls it's abort method. Elsewere do
141: * nothing.
142: *
143: * @param gs DOCUMENT ME!
144: */
145: public void abort(Service gs) {
146: if (delegate != null) {
147: if (LOGGER.isLoggable(Level.FINE)) {
148: LOGGER.fine("asking delegate for aborting the process");
149: }
150:
151: delegate.abort(gs);
152: }
153: }
154:
155: /**
156: * delegates the writing and encoding of the results of the request to the
157: * <code>GetMapDelegate</code> wich is actually processing it, and has
158: * been obtained when <code>execute(Request)</code> was called
159: *
160: * @param out the output to where the map must be written
161: *
162: * @throws ServiceException if the delegate throws a ServiceException
163: * inside its <code>writeTo(OuptutStream)</code>, mostly due to
164: * @throws IOException if the delegate throws an IOException inside its
165: * <code>writeTo(OuptutStream)</code>, mostly due to
166: * @throws IllegalStateException if this method is called before
167: * <code>execute(Request)</code> has succeed
168: */
169: public void writeTo(OutputStream out) throws ServiceException,
170: IOException {
171: if (delegate == null) {
172: throw new IllegalStateException(
173: "No GetMapDelegate is setted, make sure you have called execute and it has succeed");
174: }
175:
176: if (LOGGER.isLoggable(Level.FINER)) {
177: LOGGER.finer(new StringBuffer(
178: "asking delegate for write to ").append(out)
179: .toString());
180: }
181:
182: delegate.writeTo(out);
183: }
184:
185: /**
186: * Creates a GetMapDelegate specialized in generating the requested map
187: * format
188: *
189: * @param request a request parameter object wich holds the processed
190: * request objects, such as layers, bbox, outpu format, etc.
191: *
192: * @return A specialization of <code>GetMapDelegate</code> wich can produce
193: * the requested output map format
194: *
195: * @throws WmsException if no specialization is configured for the output
196: * format specified in <code>request</code> or if it can't be
197: * instantiated
198: */
199: private static GetFeatureInfoDelegate getDelegate(
200: GetFeatureInfoRequest request) throws WmsException {
201: String requestFormat = request.getInfoFormat();
202:
203: if (LOGGER.isLoggable(Level.FINER)) {
204: LOGGER.finer(new StringBuffer("request format is ").append(
205: requestFormat).toString());
206: }
207:
208: GetFeatureInfoDelegate curDelegate = null;
209: Class delegateClass = null;
210:
211: for (Iterator it = delegates.iterator(); it.hasNext();) {
212: curDelegate = (GetFeatureInfoDelegate) it.next();
213:
214: if (curDelegate.canProduce(requestFormat)) {
215: delegateClass = curDelegate.getClass();
216:
217: if (LOGGER.isLoggable(Level.FINER)) {
218: LOGGER.finer(new StringBuffer(
219: "found GetFeatureInfoDelegate ").append(
220: delegateClass).toString());
221: }
222:
223: break;
224: }
225: }
226:
227: if (delegateClass == null) {
228: // let's default to something sensible. If the parameter is empty we return a
229: // TextFeatureInfoResponse, so let's do the same thing here. See the "hack" comment in
230: // GetFeatureInfoKVPReader.java.
231: delegateClass = new TextFeatureInfoResponse().getClass();
232: }
233:
234: try {
235: curDelegate = (GetFeatureInfoDelegate) delegateClass
236: .newInstance();
237: } catch (Exception ex) {
238: throw new WmsException(
239: ex,
240: "Cannot obtain the map generator for the requested format",
241: "GetMapResponse::getDelegate()");
242: }
243:
244: return curDelegate;
245: }
246:
247: /**
248: * iterates over the registered Map producers and fills a list with all the
249: * map formats' MIME types that the producers can handle
250: *
251: * @return DOCUMENT ME!
252: */
253: public static List getFormats() {
254: return supportedMimeTypes;
255: }
256:
257: /* (non-Javadoc)
258: * @see org.vfny.geoserver.Response#getContentDisposition()
259: */
260: public String getContentDisposition() {
261: // TODO Auto-generated method stub
262: return null;
263: }
264: }
|