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 }