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.geoserver.platform.GeoServerExtensions;
008: import org.springframework.context.ApplicationContext;
009: import org.vfny.geoserver.Request;
010: import org.vfny.geoserver.Response;
011: import org.vfny.geoserver.ServiceException;
012: import org.vfny.geoserver.global.GeoServer;
013: import org.vfny.geoserver.global.Service;
014: import org.vfny.geoserver.wms.GetLegendGraphicProducer;
015: import org.vfny.geoserver.wms.GetLegendGraphicProducerSpi;
016: import org.vfny.geoserver.wms.WmsException;
017: import org.vfny.geoserver.wms.requests.GetLegendGraphicRequest;
018: import java.io.IOException;
019: import java.io.OutputStream;
020: import java.util.Collection;
021: import java.util.HashMap;
022: import java.util.HashSet;
023: import java.util.Iterator;
024: import java.util.Map;
025: import java.util.Set;
026: import java.util.logging.Level;
027: import java.util.logging.Logger;
028:
029: /**
030: * DOCUMENT ME!
031: *
032: * @author Gabriel Roldan, Axios Engineering
033: * @version $Id: GetLegendGraphicResponse.java 7746 2007-11-13 15:38:35Z aaime $
034: */
035: public class GetLegendGraphicResponse implements Response {
036: /** DOCUMENT ME! */
037: private static final Logger LOGGER = org.geotools.util.logging.Logging
038: .getLogger(GetLegendGraphicResponse.class.getPackage()
039: .getName());
040:
041: /**
042: * The legend graphic producer that will be used for the production of a legend in the
043: * requested format.
044: */
045: private GetLegendGraphicProducer delegate;
046:
047: /**
048: * Application Context
049: */
050: private ApplicationContext applicationContext;
051:
052: /**
053: * Creates a new GetLegendGraphicResponse object.
054: *
055: * @param applicationContext
056: */
057: public GetLegendGraphicResponse(
058: ApplicationContext applicationContext) {
059: this .applicationContext = applicationContext;
060: }
061:
062: /**
063: * Returns any extra headers that this service might want to set in the HTTP response object.
064: * @see org.vfny.geoserver.Response#getResponseHeaders()
065: */
066: public HashMap getResponseHeaders() {
067: return null;
068: }
069:
070: /**
071: * DOCUMENT ME!
072: *
073: * @param req DOCUMENT ME!
074: *
075: * @throws ServiceException DOCUMENT ME!
076: */
077: public void execute(Request req) throws ServiceException {
078: GetLegendGraphicRequest request = (GetLegendGraphicRequest) req;
079:
080: final String outputFormat = request.getFormat();
081: this .delegate = getDelegate(outputFormat);
082: this .delegate.produceLegendGraphic(request);
083: }
084:
085: /**
086: * DOCUMENT ME!
087: *
088: * @param gs DOCUMENT ME!
089: *
090: * @return DOCUMENT ME!
091: *
092: * @throws IllegalStateException DOCUMENT ME!
093: */
094: public String getContentType(GeoServer gs)
095: throws IllegalStateException {
096: if (this .delegate == null) {
097: throw new IllegalStateException(
098: "No request has been processed");
099: }
100:
101: return this .delegate.getContentType();
102: }
103:
104: /**
105: * DOCUMENT ME!
106: *
107: * @return DOCUMENT ME!
108: */
109: public String getContentEncoding() {
110: if (LOGGER.isLoggable(Level.FINER)) {
111: LOGGER.finer("returning content encoding null");
112: }
113:
114: return null;
115: }
116:
117: /**
118: * Asks the GetLegendGraphicProducer obtained in execute() to abort the
119: * process.
120: *
121: * @param gs not used.
122: */
123: public void abort(Service gs) {
124: if (this .delegate != null) {
125: if (LOGGER.isLoggable(Level.FINE)) {
126: LOGGER.fine("asking delegate for aborting the process");
127: }
128:
129: this .delegate.abort();
130: }
131: }
132:
133: /**
134: * DOCUMENT ME!
135: *
136: * @param out DOCUMENT ME!
137: *
138: * @throws ServiceException DOCUMENT ME!
139: * @throws IOException DOCUMENT ME!
140: * @throws IllegalStateException DOCUMENT ME!
141: */
142: public void writeTo(OutputStream out) throws ServiceException,
143: IOException {
144: try { // mapcontext can leak memory -- we make sure we done (see
145: // finally block)
146:
147: if (this .delegate == null) {
148: throw new IllegalStateException(
149: "No GetMapDelegate is setted, make sure you have called execute and it has succeed");
150: }
151:
152: if (LOGGER.isLoggable(Level.FINER)) {
153: LOGGER.finer(new StringBuffer(
154: "asking delegate for write to ").append(out)
155: .toString());
156: }
157:
158: this .delegate.writeTo(out);
159: } catch (Exception e) // we dont want to propogate a new error
160: {
161: if (LOGGER.isLoggable(Level.FINER)) {
162: LOGGER.finer(new StringBuffer(
163: "asking delegate for write to ").append(out)
164: .toString());
165: }
166: }
167: }
168:
169: /**
170: * Creates a GetMapDelegate specialized in generating the requested map
171: * format
172: *
173: * @param outputFormat
174: * a request parameter object wich holds the processed request
175: * objects, such as layers, bbox, outpu format, etc.
176: *
177: * @return A specialization of <code>GetMapDelegate</code> wich can
178: * produce the requested output map format
179: *
180: * @throws WmsException
181: * if no specialization is configured for the output format
182: * specified in <code>request</code> or if it can't be
183: * instantiated
184: */
185: private GetLegendGraphicProducer getDelegate(String outputFormat)
186: throws WmsException {
187: Collection producers = GeoServerExtensions
188: .extensions(GetLegendGraphicProducerSpi.class);
189: GetLegendGraphicProducerSpi factory;
190:
191: for (Iterator iter = producers.iterator(); iter.hasNext();) {
192: factory = (GetLegendGraphicProducerSpi) iter.next();
193:
194: if (factory.canProduce(outputFormat)) {
195: return factory.createLegendProducer(outputFormat);
196: }
197: }
198:
199: throw new WmsException(
200: "There is no support for creating legends in "
201: + outputFormat + " format", "InvalidFormat");
202: }
203:
204: /**
205: * Utility method to ask all the available legend graphic producer
206: * factories if they support the production of a legend graphic in the
207: * format specified.
208: *
209: * @param mimeType the MIME type of the desired legend format (e.g.
210: * "image/png").
211: *
212: * @return wether a legend producer can manage the specified format or not.
213: */
214: public static boolean supportsFormat(String mimeType,
215: ApplicationContext context) {
216: return loadLegendFormats(context).contains(mimeType);
217: }
218:
219: /**
220: * Convenient method to search and return all the supported image formats
221: * for the creation of legend graphics.
222: *
223: * @return the set of all the supported legend graphic formats.
224: */
225: public static Set getFormats(ApplicationContext context) {
226: return loadLegendFormats(context);
227: }
228:
229: /**
230: * Convenience method for processing the GetMapProducerFactorySpi extension
231: * point and returning the set of available image formats.
232: *
233: * @param applicationContext
234: * The application context.
235: *
236: */
237: private static Set loadLegendFormats(
238: ApplicationContext applicationContext) {
239: Collection producers = GeoServerExtensions
240: .extensions(GetLegendGraphicProducerSpi.class);
241: Set formats = new HashSet();
242: GetLegendGraphicProducerSpi producer;
243:
244: for (Iterator iter = producers.iterator(); iter.hasNext();) {
245: producer = (GetLegendGraphicProducerSpi) iter.next();
246: formats.addAll(producer.getSupportedFormats());
247: }
248:
249: return formats;
250: }
251:
252: public String getContentDisposition() {
253: return null;
254: }
255: }
|