001 // $HeadURL:
002 // /cvsroot/deegree/src/org/deegree/ogcwebservices/wcs/getcapabilities/WCSRequestValidator.java,v
003 // 1.6 2004/07/12 11:14:19 ap Exp $
004 /*---------------- FILE HEADER ------------------------------------------
005
006 This file is part of deegree.
007 Copyright (C) 2001-2008 by:
008 EXSE, Department of Geography, University of Bonn
009 http://www.giub.uni-bonn.de/deegree/
010 lat/lon GmbH
011 http://www.lat-lon.de
012
013 This library is free software; you can redistribute it and/or
014 modify it under the terms of the GNU Lesser General Public
015 License as published by the Free Software Foundation; either
016 version 2.1 of the License, or (at your option) any later version.
017
018 This library is distributed in the hope that it will be useful,
019 but WITHOUT ANY WARRANTY; without even the implied warranty of
020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
021 Lesser General Public License for more details.
022
023 You should have received a copy of the GNU Lesser General Public
024 License along with this library; if not, write to the Free Software
025 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
026
027 Contact:
028
029 Andreas Poth
030 lat/lon GmbH
031 Aennchenstr. 19
032 53115 Bonn
033 Germany
034 E-Mail: poth@lat-lon.de
035
036 Prof. Dr. Klaus Greve
037 Department of Geography
038 University of Bonn
039 Meckenheimer Allee 166
040 53115 Bonn
041 Germany
042 E-Mail: greve@giub.uni-bonn.de
043
044
045 ---------------------------------------------------------------------------*/
046 package org.deegree.ogcwebservices.wcs.getcapabilities;
047
048 import java.net.URI;
049 import java.net.URL;
050
051 import org.deegree.datatypes.Code;
052 import org.deegree.datatypes.CodeList;
053 import org.deegree.framework.log.ILogger;
054 import org.deegree.framework.log.LoggerFactory;
055 import org.deegree.model.crs.CRSFactory;
056 import org.deegree.model.crs.GeoTransformer;
057 import org.deegree.model.crs.UnknownCRSException;
058 import org.deegree.model.spatialschema.Envelope;
059 import org.deegree.model.spatialschema.GeometryFactory;
060 import org.deegree.ogcbase.ExceptionCode;
061 import org.deegree.ogcwebservices.CurrentUpdateSequenceException;
062 import org.deegree.ogcwebservices.InvalidParameterValueException;
063 import org.deegree.ogcwebservices.InvalidUpdateSequenceException;
064 import org.deegree.ogcwebservices.LonLatEnvelope;
065 import org.deegree.ogcwebservices.OGCWebServiceException;
066 import org.deegree.ogcwebservices.OGCWebServiceRequest;
067 import org.deegree.ogcwebservices.SupportedFormats;
068 import org.deegree.ogcwebservices.wcs.CoverageOfferingBrief;
069 import org.deegree.ogcwebservices.wcs.describecoverage.CoverageDescription;
070 import org.deegree.ogcwebservices.wcs.describecoverage.CoverageOffering;
071 import org.deegree.ogcwebservices.wcs.describecoverage.DescribeCoverage;
072 import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage;
073
074 /**
075 * @version $Revision: 9444 $
076 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
077 * @author last edited by: $Author: rbezema $
078 *
079 * @version 1.0. $Revision: 9444 $, $Date: 2008-01-08 12:00:14 +0100 (Di, 08 Jan 2008) $
080 *
081 * @since 2.0
082 */
083 public class WCSRequestValidator {
084
085 private static final ILogger LOG = LoggerFactory.getLogger( WCSRequestValidator.class );
086
087 /**
088 * validates the passed <tt>AbstractOGCWebServiceRequest</tt> which must
089 * be a request that is known by a WCS against the passed
090 * <tt>WCSCapabilities</tt>
091 *
092 * @param capabilities
093 * @param request
094 * @throws CurrentUpdateSequenceException
095 * @throws InvalidUpdateSequenceException
096 * @throws OGCWebServiceException
097 */
098 public static void validate(WCSCapabilities capabilities,
099 OGCWebServiceRequest request)
100 throws CurrentUpdateSequenceException,
101 InvalidUpdateSequenceException, OGCWebServiceException {
102 // schmitz: since we only support one version, we can actually just ignore
103 // the attribute (at least for GetCapabilities requests). I do not think
104 // it does any harm to remove it completely.
105
106 // if ( !request.getVersion().equals(capabilities.getVersion() )) {
107 // throw new InvalidParameterValueException(request.getVersion() + " is not " +
108 // "a valid version for requesting this WCS");
109 // }
110
111 if (request instanceof WCSGetCapabilities) {
112 validate(capabilities, (WCSGetCapabilities) request);
113 } else if (request instanceof GetCoverage) {
114 validate( capabilities, (GetCoverage)request );
115 } else if (request instanceof DescribeCoverage) {
116 validate(capabilities, (DescribeCoverage) request);
117 } else {
118 throw new OGCWebServiceException("Invalid request type: " + request);
119 }
120 }
121
122 /**
123 * validates the passed <tt>WCSGetCapabilities</tt> against the passed
124 * <tt>WCSCapabilities</tt>
125 *
126 * @param capabilities
127 * @param request
128 * @throws CurrentUpdateSequenceException
129 * @throws InvalidUpdateSequenceException
130 */
131 private static void validate(WCSCapabilities capabilities,
132 WCSGetCapabilities request) throws CurrentUpdateSequenceException,
133 InvalidUpdateSequenceException {
134 String rUp = request.getUpdateSequence();
135 String cUp = capabilities.getUpdateSequence();
136
137 if ((rUp != null) && (cUp != null) && (rUp.compareTo(cUp) == 0)) {
138 ExceptionCode code = ExceptionCode.CURRENT_UPDATE_SEQUENCE;
139 throw new CurrentUpdateSequenceException("WCS GetCapabilities",
140 "request update sequence: " + rUp
141 + "is equal to capabilities" + " update sequence "
142 + cUp, code);
143 }
144
145 if ((rUp != null) && (cUp != null) && (rUp.compareTo(cUp) > 0)) {
146 ExceptionCode code = ExceptionCode.INVALID_UPDATESEQUENCE;
147 throw new InvalidUpdateSequenceException("WCS GetCapabilities",
148 "request update sequence: " + rUp + " is higher then the "
149 + "capabilities update sequence " + cUp, code);
150 }
151 }
152
153 /**
154 * validates the passed <tt>DescribeCoverage</tt> against the passed
155 * <tt>WCSCapabilities</tt>
156 *
157 * @param capabilities
158 * @param request
159 * @throws InvalidParameterValueException
160 */
161 private static void validate(WCSCapabilities capabilities,
162 DescribeCoverage request) throws InvalidParameterValueException {
163 String[] coverages = request.getCoverages();
164 if (coverages != null) {
165 ContentMetadata cm = capabilities.getContentMetadata();
166 for (int i = 0; i < coverages.length; i++) {
167 if (cm.getCoverageOfferingBrief(coverages[i]) == null) {
168 throw new InvalidParameterValueException(
169 "Coverage: " + coverages[i] + "is not known by the WCS"); }
170 }
171 }
172 }
173
174 /**
175 * validates the passed <tt>GetCoverage</tt> against the passed
176 * <tt>WCSCapabilities</tt>
177 *
178 * @param capabilities
179 * @param request
180 * @throws InvalidParameterValueException
181 */
182 private static void validate(WCSCapabilities capabilities,
183 GetCoverage request) throws InvalidParameterValueException {
184 String coverage = request.getSourceCoverage();
185 ContentMetadata cm = capabilities.getContentMetadata();
186 // is coverage known by the WCS?
187 CoverageOfferingBrief cob = cm.getCoverageOfferingBrief(coverage);
188 if (cob == null) { throw new InvalidParameterValueException(
189 "Coverage: " + coverage + " is not known by the WCS"); }
190
191 URL url = cob.getConfiguration();
192 CoverageDescription cd = null;
193 try {
194 cd = CoverageDescription.createCoverageDescription(url);
195 } catch (Exception e) {
196 LOG.logError( e.getMessage(), e );
197 throw new InvalidParameterValueException( e.getMessage() );
198 }
199 CoverageOffering co = cd.getCoverageOffering(coverage);
200 if (co == null ) {
201 throw new InvalidParameterValueException("no coverage descrition " +
202 "available for requested coverage: " + coverage);
203 }
204 // validate requested format
205 String format = request.getOutput().getFormat().getCode();
206 SupportedFormats sf = co.getSupportedFormats();
207 CodeList[] codeList = sf.getFormats();
208 if (!validate(codeList, null, format)) {
209 throw new InvalidParameterValueException( "requested format: " + format
210 + " is not known by the WCS for coverage:" + coverage); }
211 // validate requested response CRS
212 String crs = request.getOutput().getCrs().getCode();
213 URI codeSpace = request.getOutput().getCrs().getCodeSpace();
214 String space = null;
215 if ( codeSpace != null ) {
216 space = codeSpace.toString();
217 }
218
219 CodeList[] rrcrs = co.getSupportedCRSs().getRequestResponseSRSs();
220 CodeList[] rescrs = co.getSupportedCRSs().getResponseSRSs();
221 if (!validate(rrcrs, space, crs) && !validate(rescrs, space, crs)) {
222 throw new InvalidParameterValueException(
223 "requested response CRS: " + crs
224 + " is not known by the WCS " + "for coverage:"
225 + coverage); }
226 // validate requested CRS
227 crs = request.getDomainSubset().getRequestSRS().getCode();
228 codeSpace = request.getDomainSubset().getRequestSRS().getCodeSpace();
229 if ( codeSpace != null ) {
230 space = codeSpace.toString();
231 }
232 CodeList[] reqcrs = co.getSupportedCRSs().getRequestSRSs();
233
234 if (!validate(rrcrs, space, crs) && !validate(reqcrs, space, crs)) {
235 throw new InvalidParameterValueException(
236 "requested request CRS: " + crs
237 + " is not known by the WCS for coverage:" + coverage); }
238 // validate requested envelope
239 Envelope envelope = request.getDomainSubset().getSpatialSubset().getEnvelope();
240 LonLatEnvelope llEnv = cob.getLonLatEnvelope();
241
242 try {
243 if ( !intersects(envelope, request.getDomainSubset().getRequestSRS(), llEnv) ) {
244 throw new InvalidParameterValueException(
245 "requested BBOX: doesn't intersect "
246 + " the area of the requested coverage: "
247 + coverage);
248 }
249 } catch ( UnknownCRSException e ) {
250 throw new InvalidParameterValueException( e );
251 }
252
253 }
254
255 /**
256 * @return true if the passed <tt>CodeList</tt> s contains the also passed
257 * codeSpace-value combination. Otherwise false will be returned
258 *
259 * @param codeList
260 * @param codeSpace
261 * @param value
262 */
263 private static boolean validate(CodeList[] codeList, String codeSpace,
264 String value) {
265 for (int i = 0; i < codeList.length; i++) {
266 if (codeList[i].validate(codeSpace, value)) { return true; }
267 }
268 return false;
269 }
270
271 private static boolean intersects(Envelope envelope, Code reqCRS,
272 LonLatEnvelope llEnv) throws UnknownCRSException {
273 Envelope latlonEnv =
274 GeometryFactory.createEnvelope(llEnv.getMin().getX(),
275 llEnv.getMin().getY(),
276 llEnv.getMax().getX(),
277 llEnv.getMax().getY(),
278 CRSFactory.create("EPSG:4326") );
279 try {
280 if ( !"EPSG:4326".equals( reqCRS.getCode() ) ) {
281 GeoTransformer gt = new GeoTransformer("EPSG:4326");
282 String crs = reqCRS.getCode();
283 envelope = gt.transform(envelope, crs );
284 }
285 } catch (Exception e) {
286 e.printStackTrace();
287 return false;
288 }
289 return envelope.intersects(latlonEnv);
290 }
291
292 }