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 java.io.ByteArrayOutputStream;
008: import java.io.IOException;
009: import java.io.OutputStream;
010: import java.util.HashMap;
011: import java.util.Set;
012: import java.util.logging.Logger;
013:
014: import javax.xml.transform.TransformerException;
015:
016: import org.springframework.context.ApplicationContext;
017: import org.vfny.geoserver.Request;
018: import org.vfny.geoserver.Response;
019: import org.vfny.geoserver.ServiceException;
020: import org.vfny.geoserver.global.GeoServer;
021: import org.vfny.geoserver.global.Service;
022: import org.vfny.geoserver.util.requests.CapabilitiesRequest;
023: import org.vfny.geoserver.wms.WmsException;
024: import org.vfny.geoserver.wms.responses.helpers.WMSCapsTransformer;
025:
026: /**
027: * Processes a WMS GetCapabilities request.
028: * <p>
029: * The response of a GetCapabilities request is general information about the
030: * service itself and specific information about the available maps.
031: * </p>
032: *
033: * @author Gabriel Roldan, Axios Engineering
034: * @version $Id: WMSCapabilitiesResponse.java 8477 2008-02-28 15:00:23Z aaime $
035: */
036: public class WMSCapabilitiesResponse implements Response {
037: /** package's logger */
038: private static final Logger LOGGER = org.geotools.util.logging.Logging
039: .getLogger(WMSCapabilitiesResponse.class.getPackage()
040: .getName());
041:
042: /**
043: * Byte array holding the raw content of the capabilities document,
044: * generated in <code>execute()</code>
045: */
046: private byte[] rawResponse;
047:
048: /**
049: * List of formats accessible via a GetMap request.
050: */
051: private Set formats;
052: private ApplicationContext applicationContext;
053:
054: public WMSCapabilitiesResponse(Set wmsGetMapFormats,
055: ApplicationContext applicationContext) {
056: this .formats = wmsGetMapFormats;
057: this .applicationContext = applicationContext;
058: }
059:
060: /**
061: * Returns any extra headers that this service might want to set in the HTTP response object.
062: * @see org.vfny.geoserver.Response#getResponseHeaders()
063: */
064: public HashMap getResponseHeaders() {
065: return null;
066: }
067:
068: /**
069: * DOCUMENT ME!
070: *
071: * @param request DOCUMENT ME!
072: *
073: * @throws ServiceException DOCUMENT ME!
074: * @throws IllegalArgumentException DOCUMENT ME!
075: * @throws WmsException DOCUMENT ME!
076: */
077: public void execute(Request request) throws ServiceException {
078: if (!(request instanceof CapabilitiesRequest)) {
079: throw new IllegalArgumentException(
080: "Not a GetCapabilities Request");
081: }
082:
083: //UpdateSequence handling for WMS: see WMS 1.1.1 page 23
084: CapabilitiesRequest capreq = (CapabilitiesRequest) request;
085: int reqUS = -1;
086: if (capreq.getUpdateSequence() != null
087: && !"".equals(capreq.getUpdateSequence().trim())) {
088: try {
089: reqUS = Integer.parseInt(capreq.getUpdateSequence());
090: } catch (NumberFormatException nfe) {
091: throw new ServiceException(
092: "GeoServer only accepts numbers in the updateSequence parameter");
093: }
094: }
095: int geoUS = request.getServiceRef().getServiceRef()
096: .getGeoServer().getUpdateSequence();
097: if (reqUS > geoUS) {
098: throw new org.geoserver.platform.ServiceException(
099: "Client supplied an updateSequence that is greater than the current sever updateSequence",
100: "InvalidUpdateSequence");
101: }
102: if (reqUS == geoUS) {
103: throw new org.geoserver.platform.ServiceException(
104: "WMS capabilities document is current (updateSequence = "
105: + geoUS + ")", "CurrentUpdateSequence");
106: }
107: //otherwise it's a normal response...
108:
109: WMSCapsTransformer transformer = new WMSCapsTransformer(request
110: .getBaseUrl(), formats, applicationContext);
111:
112: // if (request.getWFS().getGeoServer().isVerbose()) {
113: transformer.setIndentation(2);
114:
115: // }
116: ByteArrayOutputStream out = new ByteArrayOutputStream();
117:
118: try {
119: transformer.transform(request, out);
120: } catch (TransformerException e) {
121: throw new WmsException(e);
122: }
123:
124: this .rawResponse = out.toByteArray();
125: }
126:
127: /**
128: * Returns the fixed capabilities MIME type (application/vnd.ogc.wms_xml)
129: * as specified in whe WMS spec, version 1.1.1, section 6.5.3, table 3.
130: *
131: * @param gs DOCUMENT ME!
132: *
133: * @return the capabilities document MIME type.
134: *
135: * @throws IllegalStateException if the response was not yet produced.
136: */
137: public String getContentType(GeoServer gs)
138: throws IllegalStateException {
139: if (rawResponse == null) {
140: throw new IllegalStateException(
141: "execute() not called or not succeed.");
142: }
143:
144: return WMSCapsTransformer.WMS_CAPS_MIME;
145: }
146:
147: /**
148: * Just returns <code>null</code>, since no special encoding is applyed to
149: * the output data.
150: *
151: * @return <code>null</code>
152: */
153: public String getContentEncoding() {
154: return null;
155: }
156:
157: /**
158: * Writes the capabilities document generated in <code>execute()</code> to
159: * the given output stream.
160: *
161: * @param out the capabilities document destination
162: *
163: * @throws ServiceException never, since the whole content was aquired in
164: * <code>execute()</code>
165: * @throws IOException if it is thrown while writing to <code>out</code>
166: * @throws IllegalStateException if <code>execute()</code> was not
167: * called/succeed before this method is called.
168: */
169: public void writeTo(OutputStream out) throws ServiceException,
170: IOException {
171: if (rawResponse == null) {
172: throw new IllegalStateException("No raw response presents!");
173: }
174:
175: out.write(rawResponse);
176: }
177:
178: /**
179: * Does nothing, since no processing is done after <code>execute()</code>
180: * has returned.
181: *
182: * @param gs the service instance
183: */
184: public void abort(Service gs) {
185: }
186:
187: /*
188: * (non-Javadoc)
189: *
190: * @see org.vfny.geoserver.Response#getContentDisposition()
191: */
192: public String getContentDisposition() {
193: return null;
194: }
195: }
|