001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_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    }