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.requests;
006:
007: import org.vfny.geoserver.Request;
008: import org.vfny.geoserver.ServiceException;
009: import org.vfny.geoserver.global.Data;
010: import org.vfny.geoserver.global.FeatureTypeInfo;
011: import org.vfny.geoserver.global.MapLayerInfo;
012: import org.vfny.geoserver.global.WMS;
013: import org.vfny.geoserver.wms.WmsException;
014: import org.vfny.geoserver.wms.servlets.WMService;
015:
016: import java.util.List;
017: import java.util.Map;
018: import java.util.NoSuchElementException;
019: import java.util.logging.Logger;
020: import javax.servlet.http.HttpServletRequest;
021: import org.vfny.geoserver.global.CoverageInfo;
022:
023: /**
024: * Builds a GetFeatureInfo request object given by a set of CGI parameters
025: * supplied in the constructor.
026: *
027: * <p>
028: * Request parameters:
029: * </p>
030: *
031: * @author Gabriel Roldan, Axios Engineering
032: * @version $Id: GetFeatureInfoKvpReader.java 8418 2008-02-18 14:47:17Z aaime $
033: */
034: public class GetFeatureInfoKvpReader extends WmsKvpRequestReader {
035: /** DOCUMENT ME! */
036: private static final Logger LOGGER = org.geotools.util.logging.Logging
037: .getLogger("org.vfny.geoserver.requests.readers.wms");
038:
039: /** the request wich will be built by getRequest method */
040: private GetFeatureInfoRequest request;
041:
042: /** GetMap request reader used to parse the map context parameters needed. */
043: private GetMapKvpReader getMapReader;
044:
045: /**
046: * Creates a new GetMapKvpReader object.
047: * @param kvpPairs Key Values pairs of the request
048: * @param service The service handling the request
049: */
050: public GetFeatureInfoKvpReader(Map kvpPairs, WMService service) {
051: super (kvpPairs, service);
052: getMapReader = new GetMapKvpReader(kvpPairs, service);
053: }
054:
055: /**
056: * Produces a <code>GetMapRequest</code> instance by parsing the GetMap
057: * mandatory, optional and custom parameters.
058: *
059: * @param httpRequest the servlet request who's application object holds
060: * the server configuration
061: *
062: * @return a <code>GetMapRequest</code> completely setted up upon the
063: * parameters passed to this reader
064: *
065: * @throws ServiceException DOCUMENT ME!
066: * @throws WmsException DOCUMENT ME!
067: */
068: public Request getRequest(HttpServletRequest httpRequest)
069: throws ServiceException {
070: WMService service = (WMService) getServiceRef();
071: WMS wms = service.getWMS();
072: request = new GetFeatureInfoRequest(service);
073: request.setHttpServletRequest(httpRequest);
074:
075: String version = getRequestVersion();
076: request.setVersion(version);
077:
078: getMapReader.setStylesRequired(false);
079:
080: GetMapRequest getMapPart = (GetMapRequest) getMapReader
081: .getRequest(httpRequest);
082: request.setGetMapRequest(getMapPart);
083:
084: MapLayerInfo[] layers = parseLayers(wms);
085: request.setQueryLayers(layers);
086:
087: String format = getValue("INFO_FORMAT");
088:
089: if (format == null) {
090: //HACK: how we define the default info format?
091: //Not sure I understand the question. If we don't like it here
092: //then put it as the default in the FeatureInfoRequest. If
093: //we want to allow users to be able to set it then we can put
094: //it as a config parameter in the WMS service section. -ch
095: format = "text/plain";
096: }
097:
098: request.setInfoFormat(format);
099:
100: request.setFeatureCount(1); // DJB: according to the WMS spec (7.3.3.7 FEATURE_COUNT) this should be 1. also tested for by cite
101:
102: try {
103: int maxFeatures = Integer
104: .parseInt(getValue("FEATURE_COUNT"));
105: request.setFeatureCount(maxFeatures);
106: } catch (NumberFormatException ex) {
107: //do nothing, FEATURE_COUNT is optional
108: }
109:
110: try {
111: int x = Integer.parseInt(getValue("X"));
112: int y = Integer.parseInt(getValue("Y"));
113: request.setXPixel(x);
114: request.setYPixel(y);
115: } catch (NumberFormatException ex) {
116: throw new WmsException("X and Y incorrectly specified");
117: }
118:
119: String exceptionsFormat = getValue("EXCEPTIONS");
120: request.setExeptionFormat(exceptionsFormat);
121:
122: return request;
123: }
124:
125: /**
126: * Obtains the FeatureTypeInfo objects of the layers to query
127: * given by the <code>QUERY_LAYERS</code>parameter.
128: *
129: * @return the list of layers to query.
130: *
131: * @throws WmsException if the parameter <code>QUERY_LAYERS</code> does not
132: * exists, has no layer names, or has at least an invalid layer name.
133: */
134: private MapLayerInfo[] parseLayers(WMS wms) throws WmsException {
135: List layers = readFlat(getValue("QUERY_LAYERS"),
136: INNER_DELIMETER);
137:
138: // expand base layers, if there is any
139: if (wms.getBaseMapLayers() != null) {
140: for (int i = 0; i < layers.size(); i++) {
141: String layerGroup = (String) wms.getBaseMapLayers()
142: .get(layers.get(i));
143: if (layerGroup != null) {
144: List layerGroupExpanded = readFlat(layerGroup,
145: INNER_DELIMETER);
146: layers.remove(i);
147: layers.addAll(i, layerGroupExpanded);
148: }
149: }
150: }
151:
152: // remove coverage layers, we cannot query them
153: Data catalog = request.getWMS().getData();
154: /*for (Iterator it = layers.iterator(); it.hasNext();) {
155: String layerName = (String) it.next();
156: if(catalog.getLayerType(layerName) != Data.TYPE_VECTOR)
157: it.remove();
158: }*/
159: int layerCount = layers.size();
160: if (layerCount == 0) {
161: throw new WmsException(
162: "No QUERY_LAYERS has been requested, or no queriable layer in the request anyways",
163: getClass().getName());
164: }
165: MapLayerInfo[] layerInfos = new MapLayerInfo[layerCount];
166: String layerName = null;
167: for (int i = 0; i < layerCount; i++) {
168: layerName = (String) layers.get(i);
169: layerInfos[i] = catalog.getMapLayerInfo(layerName);
170: }
171:
172: return layerInfos;
173: }
174: }
|