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