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