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