001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/enterprise/servlet/WPVSHandler.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    
037    package org.deegree.enterprise.servlet;
038    
039    import java.awt.Color;
040    import java.awt.Dimension;
041    import java.awt.Graphics;
042    import java.awt.Image;
043    import java.awt.image.BufferedImage;
044    import java.io.IOException;
045    import java.io.OutputStream;
046    import java.io.PrintWriter;
047    
048    import javax.servlet.http.HttpServletResponse;
049    
050    import org.deegree.enterprise.ServiceException;
051    import org.deegree.framework.log.ILogger;
052    import org.deegree.framework.log.LoggerFactory;
053    import org.deegree.framework.util.CharsetUtils;
054    import org.deegree.framework.util.ImageUtils;
055    import org.deegree.framework.util.MimeTypeMapper;
056    import org.deegree.framework.util.StringTools;
057    import org.deegree.framework.xml.DOMPrinter;
058    import org.deegree.ogcwebservices.OGCWebService;
059    import org.deegree.ogcwebservices.OGCWebServiceException;
060    import org.deegree.ogcwebservices.OGCWebServiceRequest;
061    import org.deegree.ogcwebservices.wpvs.WPVService;
062    import org.deegree.ogcwebservices.wpvs.WPVServiceFactory;
063    import org.deegree.ogcwebservices.wpvs.XMLFactory;
064    import org.deegree.ogcwebservices.wpvs.capabilities.WPVSCapabilities;
065    import org.deegree.ogcwebservices.wpvs.capabilities.WPVSCapabilitiesDocument;
066    import org.deegree.ogcwebservices.wpvs.configuration.WPVSConfiguration;
067    import org.deegree.ogcwebservices.wpvs.operation.Get3DFeatureInfoResponse;
068    import org.deegree.ogcwebservices.wpvs.operation.GetView;
069    import org.deegree.ogcwebservices.wpvs.operation.GetViewResponse;
070    import org.w3c.dom.Node;
071    
072    /**
073     * Handler for the Web Perspective View Service (WPVS).
074     * 
075     * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a>
076     * @author last edited by: $Author: aschmitz $
077     * 
078     * @version 2.0, $Revision: 23585 $, $Date: 2010-04-13 14:07:18 +0200 (Di, 13 Apr 2010) $
079     * 
080     * @since 2.0
081     */
082    public class WPVSHandler extends AbstractOWServiceHandler {
083    
084        private static ILogger LOG = LoggerFactory.getLogger( WPVSHandler.class );
085    
086        /**
087         * Performs the passed OGCWebServiceRequest by accessing service from the pool and passing the request to it
088         * 
089         * @param request
090         *            the incoming web service request
091         * @param httpResponse
092         *            the outgoing web serivce response
093         * @throws ServiceException
094         * @throws OGCWebServiceException
095         */
096        public void perform( OGCWebServiceRequest request, HttpServletResponse httpResponse )
097                                throws ServiceException, OGCWebServiceException {
098    
099            LOG.logDebug( StringTools.concat( 200, "Performing request: ", request.toString() ) );
100    
101            OGCWebService service = WPVServiceFactory.createInstance();
102    
103            try {
104                Object response = service.doService( request );
105                if ( response instanceof WPVSCapabilities ) {
106                    sendGetCapabilitiesResponse( httpResponse, (WPVSCapabilities) response );
107                } else if ( response instanceof GetViewResponse ) {
108                    sendGetViewResponse( httpResponse, (GetViewResponse) response );
109                } else if ( response instanceof Get3DFeatureInfoResponse ) {
110                    sendGet3DFeatureInfoResponse( httpResponse, (Get3DFeatureInfoResponse) response );
111                } else {
112                    String s = ( response == null ? "null response object" : response.getClass().getName() );
113                    // this is not really nice...because excepts get cought later on below
114                    throw new OGCWebServiceException( getClass().getName(),
115                                                      StringTools.concat( 200, "Unknown response class: '", s, "'." ) );
116                }
117            } catch ( OGCWebServiceException e ) {
118    
119                LOG.logError( "Error performing WPVFS request.", e );
120                if ( request instanceof GetView
121                     && ( "INIMAGE".equalsIgnoreCase( ( (GetView) request ).getExceptionFormat() ) ) ) {
122                    sendExceptionImage( httpResponse, e, (GetView) request );
123    
124                } else {
125                    sendException( httpResponse, e );
126                }
127            }
128    
129        }
130    
131        // TODO common to WMS
132        private void sendExceptionImage( HttpServletResponse httpResponse, OGCWebServiceException e, GetView request ) {
133    
134            Dimension d = request.getImageDimension();
135    
136            BufferedImage bi = new BufferedImage( d.width, d.height, BufferedImage.TYPE_INT_RGB );
137            Graphics g = bi.getGraphics();
138            g.setColor( Color.WHITE );
139            g.fillRect( 0, 0, d.width, d.height );
140            g.setColor( Color.BLUE );
141    
142            String s = e.getLocator();
143            String location = s != null ? s : "Unknown";
144            s = e.getMessage();
145            String message = s != null ? s : "Unknown reason!";
146    
147            g.drawString( location, 5, 20 );
148            g.drawString( message, 15, 50 );
149            String mime = MimeTypeMapper.toMimeType( request.getOutputFormat() );
150            g.dispose();
151            writeImage( bi, mime, httpResponse );
152        }
153    
154        // TODO common to WMS
155        private void writeImage( Object output, String mime, HttpServletResponse resp ) {
156            try {
157                OutputStream os = null;
158                resp.setContentType( mime );
159    
160                if ( mime.equalsIgnoreCase( "image/gif" ) ) {
161                    os = resp.getOutputStream();
162                    ImageUtils.saveImage( (BufferedImage) output, os, "gif", 1 );
163                } else if ( mime.equalsIgnoreCase( "image/jpg" ) || mime.equalsIgnoreCase( "image/jpeg" ) ) {
164                    os = resp.getOutputStream();
165                    ImageUtils.saveImage( (BufferedImage) output, os, "jpeg", 1 );
166                } else if ( mime.equalsIgnoreCase( "image/png" ) ) {
167                    os = resp.getOutputStream();
168                    ImageUtils.saveImage( (BufferedImage) output, os, "png", 1 );
169                } else if ( mime.equalsIgnoreCase( "image/tif" ) || mime.equalsIgnoreCase( "image/tiff" ) ) {
170                    os = resp.getOutputStream();
171                    ImageUtils.saveImage( (BufferedImage) output, os, "tif", 1 );
172                } else if ( mime.equalsIgnoreCase( "image/bmp" ) ) {
173                    os = resp.getOutputStream();
174                    ImageUtils.saveImage( (BufferedImage) output, os, "bmp", 1 );
175                } else if ( mime.equalsIgnoreCase( "image/svg+xml" ) ) {
176                    os = resp.getOutputStream();
177                    PrintWriter pw = new PrintWriter( os );
178                    DOMPrinter.printNode( pw, (Node) output );
179                    pw.close();
180                } else {
181                    resp.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() );
182                    os = resp.getOutputStream();
183                    OGCWebServiceException exce = new OGCWebServiceException( "WMS:writeImage",
184                                                                              "unsupported image format: " + mime );
185                    sendExceptionReport( resp, exce );
186                }
187    
188                os.close();
189            } catch ( Exception e ) {
190                LOG.logError( e.getMessage(), e );
191            }
192        }
193    
194        /**
195         * Sends the result of a someWPVService.doService( request ) bacn to the client
196         * 
197         * @param httpResponse
198         *            the response object used to pipe the result
199         * @param getViewResponse
200         *            the actua result to be sent
201         */
202        private void sendGetViewResponse( HttpServletResponse httpResponse, GetViewResponse getViewResponse ) {
203    
204            String mime = MimeTypeMapper.toMimeType( getViewResponse.getOutputFormat() );
205            httpResponse.setContentType( mime );
206    
207            // GetView response is, for the time being, always an image
208            writeImage( getViewResponse.getOutput(), httpResponse, mime );
209    
210            System.gc();
211        }
212    
213        /**
214         * Sends the response to a GetCapabilities request to the client.
215         * 
216         * @param httpResponse
217         * @param capabilities
218         * @throws OGCWebServiceException
219         *             if an exception occurs which can be propagated to the client
220         */
221        private void sendGetCapabilitiesResponse( HttpServletResponse httpResponse, WPVSCapabilities capabilities )
222                                throws OGCWebServiceException {
223            try {
224                httpResponse.setContentType( "text/xml" );
225                WPVSCapabilitiesDocument document = XMLFactory.export( capabilities );
226                document.write( httpResponse.getOutputStream() );
227            } catch ( IOException e ) {
228                LOG.logError( "Error sending GetCapabilities response.", e );
229    
230                throw new OGCWebServiceException( getClass().getName(),
231                                                  "Error exporting capabilities for GetCapabilities response." );
232            }
233        }
234    
235        /**
236         * Sends the response to a Get3DFeatureInfo request to the client.
237         * 
238         * @param httpResponse
239         * @param response
240         * @throws OGCWebServiceException
241         *             if an exception occurs which can be propagated to the client
242         */
243        private void sendGet3DFeatureInfoResponse( HttpServletResponse httpResponse, Get3DFeatureInfoResponse response )
244                                throws OGCWebServiceException {
245            try {
246                httpResponse.setContentType( "text/xml" );
247    
248                PrintWriter pw = httpResponse.getWriter();
249                String s = response.get3DFeatureInfo();
250                pw.print( s );
251            } catch ( IOException e ) {
252                LOG.logError( "Error sendingGet3DFeatureInfo response.", e );
253    
254                throw new OGCWebServiceException( getClass().getName(),
255                                                  "Error exporting Info for Get3DFeatureInfo response." );
256            }
257        }
258    
259        /**
260         * Writes an output of a GetView request to the <code>httpResponse</code> using the <code>mime</code> type.
261         * 
262         * @param output
263         *            the image to be sent back
264         * @param httpResponse
265         *            the response to pipe the image
266         * @param mime
267         *            the type of image
268         */
269        private void writeImage( Image output, HttpServletResponse httpResponse, String mime ) {
270            try {
271    
272                OutputStream os = httpResponse.getOutputStream();
273                httpResponse.setContentType( mime );
274    
275                if ( mime.equalsIgnoreCase( "image/jpg" ) || mime.equalsIgnoreCase( "image/jpeg" ) ) {
276    
277                    OGCWebService service = WPVServiceFactory.createInstance();
278                    WPVSConfiguration config = (WPVSConfiguration) ( (WPVService) service ).getCapabilities();
279                    float quality = config.getDeegreeParams().getViewQuality();
280                    ImageUtils.saveImage( (BufferedImage) output, os, "jpeg", quality );
281                } else if ( mime.equalsIgnoreCase( "image/png" ) ) {
282                    ImageUtils.saveImage( (BufferedImage) output, os, "png", 1 );
283                } else if ( mime.equalsIgnoreCase( "image/tif" ) || mime.equalsIgnoreCase( "image/tiff" ) ) {
284                    ImageUtils.saveImage( (BufferedImage) output, os, "tiff", 1 );
285                } else if ( mime.equalsIgnoreCase( "image/bmp" ) ) {
286                    ImageUtils.saveImage( (BufferedImage) output, os, "bmp", 1 );
287                } else {
288                    httpResponse.setContentType( "text/xml" );
289                    os = httpResponse.getOutputStream();
290                    OGCWebServiceException exce = new OGCWebServiceException( "WMS:writeImage",
291                                                                              "unsupported image format: " + mime );
292                    sendExceptionReport( httpResponse, exce );
293                }
294    
295                os.close();
296            } catch ( Exception e ) {
297                LOG.logError( "-", e );
298            }
299        }
300    }