001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/enterprise/servlet/WCSHandler.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2008 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53115 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 043 ---------------------------------------------------------------------------*/ 044 package org.deegree.enterprise.servlet; 045 046 import java.io.IOException; 047 import java.io.OutputStream; 048 import java.io.StringReader; 049 import java.net.URL; 050 import java.util.ArrayList; 051 import java.util.List; 052 053 import javax.servlet.http.HttpServletResponse; 054 055 import org.deegree.datatypes.parameter.GeneralParameterValueIm; 056 import org.deegree.datatypes.parameter.OperationParameterIm; 057 import org.deegree.enterprise.ServiceException; 058 import org.deegree.framework.log.ILogger; 059 import org.deegree.framework.log.LoggerFactory; 060 import org.deegree.framework.util.CharsetUtils; 061 import org.deegree.framework.util.StringTools; 062 import org.deegree.framework.xml.XMLFragment; 063 import org.deegree.framework.xml.XSLTDocument; 064 import org.deegree.i18n.Messages; 065 import org.deegree.model.coverage.grid.Format; 066 import org.deegree.model.coverage.grid.GridCoverage; 067 import org.deegree.model.coverage.grid.GridCoverageExchange; 068 import org.deegree.model.coverage.grid.GridCoverageWriter; 069 import org.deegree.model.spatialschema.Envelope; 070 import org.deegree.ogcwebservices.ExceptionReport; 071 import org.deegree.ogcwebservices.OGCWebServiceException; 072 import org.deegree.ogcwebservices.OGCWebServiceRequest; 073 import org.deegree.ogcwebservices.wcs.CoverageOfferingBrief; 074 import org.deegree.ogcwebservices.wcs.WCService; 075 import org.deegree.ogcwebservices.wcs.WCServiceFactory; 076 import org.deegree.ogcwebservices.wcs.describecoverage.CoverageDescription; 077 import org.deegree.ogcwebservices.wcs.describecoverage.CoverageOffering; 078 import org.deegree.ogcwebservices.wcs.describecoverage.InvalidCoverageDescriptionExcpetion; 079 import org.deegree.ogcwebservices.wcs.getcapabilities.ContentMetadata; 080 import org.deegree.ogcwebservices.wcs.getcapabilities.WCSCapabilities; 081 import org.deegree.ogcwebservices.wcs.getcapabilities.WCSGetCapabilities; 082 import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage; 083 import org.deegree.ogcwebservices.wcs.getcoverage.ResultCoverage; 084 import org.deegree.ogcwebservices.wcs.getcoverage.SpatialSubset; 085 import org.deegree.owscommon.XMLFactory; 086 import org.xml.sax.SAXException; 087 088 /** 089 * Dispatcher for WCService. 090 * 091 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> 092 * @author last edited by: $Author: apoth $ 093 * 094 * @version 1.0. $Revision: 9338 $, $Date: 2007-12-27 13:31:31 +0100 (Do, 27 Dez 2007) $ 095 * 096 * @since 2.0 097 */ 098 class WCSHandler extends AbstractOWServiceHandler { 099 100 private static ILogger LOG = LoggerFactory.getLogger( WCSHandler.class ); 101 102 /** 103 * 104 */ 105 WCSHandler() { 106 LOG.logDebug( "New WCSHandler instance created: " + this.getClass().getName() ); 107 } 108 109 /** 110 * 111 */ 112 public void perform( OGCWebServiceRequest request, HttpServletResponse response ) 113 throws ServiceException, OGCWebServiceException { 114 115 try { 116 Object serviceRes = this.getService().doService( request ); 117 118 if ( serviceRes instanceof OGCWebServiceException ) { 119 sendException( response, (OGCWebServiceException) serviceRes ); 120 } else if ( response instanceof Exception ) { 121 sendException( response, (Exception) serviceRes ); 122 } else if ( serviceRes instanceof ResultCoverage ) { 123 SpatialSubset spsu = ( (GetCoverage) request ).getDomainSubset().getSpatialSubset(); 124 Envelope size = (Envelope) spsu.getGrid(); 125 try { 126 sendCoverage( response, (ResultCoverage) serviceRes, size ); 127 } catch ( Exception e ) { 128 sendException( response, e ); 129 } 130 } else if ( serviceRes instanceof WCSCapabilities ) { 131 sendCapabilities( response, (WCSGetCapabilities) request, (WCSCapabilities) serviceRes ); 132 } else if ( serviceRes instanceof CoverageDescription ) { 133 sendCoverageDescription( response, (CoverageDescription) serviceRes ); 134 } else { 135 String s = Messages.getMessage( "WCS_UNKNOWN_RESPONSE_CLASS", serviceRes.getClass().getName() ); 136 throw new OGCWebServiceException( this.getClass().getName(), s ); 137 } 138 } catch ( Exception e ) { 139 sendException( response, e ); 140 } 141 } 142 143 /** 144 * sends the passed <tt>WCSCapabilities</tt> to the calling client 145 * 146 * @param response 147 * <tt>HttpServletResponse</tt> for opening stream to the client 148 * @param serviceRes 149 * object to send 150 */ 151 private void sendCapabilities( HttpServletResponse response, WCSGetCapabilities owsr, WCSCapabilities serviceRes ) { 152 StringBuffer sb = new StringBuffer( 1000 ); 153 sb.append( "<?xml version=\"1.0\" encoding='" + CharsetUtils.getSystemCharset() + "'?>" ); 154 sb.append( "<xsl:stylesheet version=\"1.0\" " ); 155 sb.append( "xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" " ); 156 sb.append( "xmlns:wcs=\"http://www.opengis.net/wcs\" " ); 157 sb.append( "xmlns:deegree=\"http://www.deegree.org/wcs\">" ); 158 sb.append( "<xsl:template match=\"wcs:WCS_Capabilities\">" + "<xsl:copy-of select=\"XXX\"/>" ); 159 sb.append( "</xsl:template>" + "</xsl:stylesheet>" ); 160 String xslt = sb.toString(); 161 try { 162 XMLFragment doc = org.deegree.ogcwebservices.wcs.XMLFactory.export( serviceRes ); 163 String[] sections = owsr.getSections(); 164 165 if ( sections != null && sections.length > 0 ) { 166 // filter out the requested section 167 if ( sections[0].equals( "/WCS_Capabilities/Service" ) ) { 168 xslt = StringTools.replace( xslt, "XXX", "./wcs:Service", false ); 169 } else if ( sections[0].equals( "/WCS_Capabilities/Capability" ) ) { 170 xslt = StringTools.replace( xslt, "XXX", "./wcs:Capability", false ); 171 } else if ( sections[0].equals( "/WCS_Capabilities/ContentMetadata" ) ) { 172 xslt = StringTools.replace( xslt, "XXX", "./wcs:ContentMetadata", false ); 173 } else { 174 xslt = StringTools.replace( xslt, "XXX", ".", false ); 175 } 176 XSLTDocument xslSheet = new XSLTDocument(); 177 xslSheet.load( new StringReader( xslt ), XMLFragment.DEFAULT_URL ); 178 doc = xslSheet.transform( doc ); 179 } 180 181 response.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() ); 182 OutputStream os = response.getOutputStream(); 183 doc.write( os ); 184 os.close(); 185 } catch ( Exception e ) { 186 LOG.logError( "ERROR: " + StringTools.stackTraceToString( e ), e ); 187 } 188 } 189 190 @Override 191 public void sendException( HttpServletResponse response, Exception exc ) { 192 OGCWebServiceException ogc; 193 194 if ( exc instanceof OGCWebServiceException ) { 195 ogc = (OGCWebServiceException) exc; 196 } else { 197 ogc = new OGCWebServiceException( exc.getMessage() ); 198 } 199 200 ExceptionReport report = new ExceptionReport( new OGCWebServiceException[] { ogc } ); 201 202 try { 203 response.setContentType( "application/vnd.ogc.se_xml" ); 204 XMLFragment reportDocument = XMLFactory.exportNS( report ); 205 OutputStream os = response.getOutputStream(); 206 reportDocument.write( os ); 207 os.close(); 208 } catch ( Exception e ) { 209 LOG.logError( "Error sending exception report: ", e ); 210 } 211 212 } 213 214 /** 215 * sends the passed <tt>CoverageDescription</tt> to the calling client 216 * 217 * @param response 218 * <tt>HttpServletResponse</tt> for opening stream to the client 219 * @param serviceRes 220 * object to send 221 */ 222 private void sendCoverageDescription( HttpServletResponse response, CoverageDescription serviceRes ) { 223 try { 224 XMLFragment doc = org.deegree.ogcwebservices.wcs.XMLFactory.export( serviceRes ); 225 response.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() ); 226 OutputStream os = response.getOutputStream(); 227 doc.write( os ); 228 os.close(); 229 } catch ( Exception e ) { 230 LOG.logError( "ERROR: " + StringTools.stackTraceToString( e ), e ); 231 } 232 } 233 234 /** 235 * writes the <tt>GridCoverage</tt> that is encapsulated within the <tt>ResultCoverage</tt> 236 * into the <tt>OutputStream</tt> taken from the passed <tt>HttpServletResponse</tt> 237 * 238 * @param response 239 * destination for writing the result coverage 240 * @param serviceRes 241 * response to a GetCoverage request 242 * @param size 243 * desired size of the GridCoverage 244 * @throws IOException 245 * @throws ServiceException 246 * @throws SAXException 247 * @throws InvalidCoverageDescriptionExcpetion 248 */ 249 private void sendCoverage( HttpServletResponse response, ResultCoverage serviceRes, Envelope size ) 250 throws IOException, InvalidCoverageDescriptionExcpetion, SAXException, ServiceException { 251 OutputStream os = response.getOutputStream(); 252 Format format = new Format( serviceRes.getDesiredOutputFormat() ); 253 String frmt = format.getName(); 254 if ( frmt.equalsIgnoreCase( "png" ) ) { 255 frmt = "image/png"; 256 } else if ( frmt.equalsIgnoreCase( "bmp" ) ) { 257 frmt = "image/bmp"; 258 } else if ( frmt.equalsIgnoreCase( "tif" ) || frmt.equalsIgnoreCase( "tiff" ) 259 || frmt.equalsIgnoreCase( "geotiff" ) ) { 260 frmt = "image/tiff"; 261 } else if ( frmt.equalsIgnoreCase( "gif" ) ) { 262 frmt = "image/gif"; 263 } else if ( frmt.equalsIgnoreCase( "jpg" ) || frmt.equalsIgnoreCase( "jpeg" ) ) { 264 frmt = "image/jpeg"; 265 } else if ( frmt.equalsIgnoreCase( "GML2" ) || frmt.equalsIgnoreCase( "GML3" ) || frmt.equalsIgnoreCase( "GML" ) ) { 266 frmt = "application/vnd.ogc.gml"; 267 } else if ( frmt.equalsIgnoreCase( "XYZ" ) ) { 268 frmt = "plain/text"; 269 } else { 270 frmt = "application/octet-stream"; 271 } 272 response.setContentType( frmt ); 273 274 GetCoverage req = serviceRes.getRequest(); 275 List<GeneralParameterValueIm> list = new ArrayList<GeneralParameterValueIm>( 20 ); 276 OperationParameterIm op = new OperationParameterIm( "addr", null, OGCServletController.address ); 277 list.add( new GeneralParameterValueIm( op ) ); 278 op = new OperationParameterIm( "width", null, new Integer( (int) size.getWidth() + 1 ) ); 279 list.add( new GeneralParameterValueIm( op ) ); 280 op = new OperationParameterIm( "height", null, new Integer( (int) size.getHeight() + 1 ) ); 281 list.add( new GeneralParameterValueIm( op ) ); 282 op = new OperationParameterIm( "service", null, "WCS" ); 283 list.add( new GeneralParameterValueIm( op ) ); 284 op = new OperationParameterIm( "version", null, req.getVersion() ); 285 list.add( new GeneralParameterValueIm( op ) ); 286 op = new OperationParameterIm( "coverage", null, req.getSourceCoverage() ); 287 list.add( new GeneralParameterValueIm( op ) ); 288 op = new OperationParameterIm( "crs", null, req.getDomainSubset().getRequestSRS().getCode() ); 289 list.add( new GeneralParameterValueIm( op ) ); 290 op = new OperationParameterIm( "response_crs", null, req.getOutput().getCrs().getCode() ); 291 list.add( new GeneralParameterValueIm( op ) ); 292 Envelope env = req.getDomainSubset().getSpatialSubset().getEnvelope(); 293 String s = StringTools.concat( 100, new Double( env.getMin().getX() ), ",", new Double( env.getMin().getY() ), 294 ",", new Double( env.getMax().getX() ), ",", new Double( env.getMax().getY() ) ); 295 op = new OperationParameterIm( "BBOX", null, s ); 296 list.add( new GeneralParameterValueIm( op ) ); 297 op = new OperationParameterIm( "FORMAT", null, "GeoTiff" ); 298 list.add( new GeneralParameterValueIm( op ) ); 299 op = new OperationParameterIm( "Request", null, "GetCoverage" ); 300 list.add( new GeneralParameterValueIm( op ) ); 301 302 GeneralParameterValueIm[] gpvs = new GeneralParameterValueIm[list.size()]; 303 if ( serviceRes.getCoverage() != null ) { 304 CoverageOffering co = getCoverageOffering( req ); 305 GridCoverageExchange gce = new GridCoverageExchange( co ); 306 GridCoverageWriter writer = gce.getWriter( os, format ); 307 writer.write( (GridCoverage) serviceRes.getCoverage(), list.toArray( gpvs ) ); 308 } else { 309 s = Messages.getMessage( "WCSHandler.NULLCOVERAGE" ); 310 OGCWebServiceException owse = new OGCWebServiceException( getClass().getName(), s ); 311 sendException( response, owse ); 312 } 313 314 os.close(); 315 316 } 317 318 /** 319 * 320 * @param request 321 * @return 322 * @throws IOException 323 * @throws SAXException 324 * @throws InvalidCoverageDescriptionExcpetion 325 * @throws ServiceException 326 */ 327 private CoverageOffering getCoverageOffering( GetCoverage request ) 328 throws IOException, SAXException, InvalidCoverageDescriptionExcpetion, ServiceException { 329 330 ContentMetadata cm = ((WCSCapabilities)getService().getCapabilities()).getContentMetadata(); 331 CoverageOfferingBrief cob = cm.getCoverageOfferingBrief( request.getSourceCoverage() ); 332 URL url = cob.getConfiguration(); 333 CoverageDescription cd = CoverageDescription.createCoverageDescription( url ); 334 CoverageOffering co = cd.getCoverageOffering( request.getSourceCoverage() ); 335 336 return co; 337 } 338 339 /** 340 * @return a service instance 341 * @throws ServiceException 342 */ 343 public WCService getService() 344 throws ServiceException { 345 346 WCService service = null; 347 try { 348 service = WCServiceFactory.getService(); 349 } catch ( Exception e ) { 350 LOG.logError( "ERROR: " + StringTools.stackTraceToString( e ), e ); 351 throw new ServiceException( e ); 352 } 353 354 return service; 355 } 356 357 }