001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/enterprise/servlet/WMSHandler.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 Aennchenstr. 19
030 53115 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 static javax.imageio.ImageIO.write;
047
048 import java.awt.Color;
049 import java.awt.Graphics;
050 import java.awt.image.BufferedImage;
051 import java.io.ByteArrayOutputStream;
052 import java.io.IOException;
053 import java.io.OutputStream;
054 import java.io.OutputStreamWriter;
055 import java.io.PrintWriter;
056 import java.io.StringReader;
057 import java.io.Writer;
058 import java.net.MalformedURLException;
059 import java.net.URISyntaxException;
060 import java.net.URL;
061 import java.util.LinkedList;
062 import java.util.List;
063
064 import javax.servlet.http.HttpServletResponse;
065 import javax.xml.transform.Source;
066 import javax.xml.transform.TransformerException;
067 import javax.xml.transform.stream.StreamResult;
068 import javax.xml.transform.stream.StreamSource;
069
070 import org.deegree.datatypes.QualifiedName;
071 import org.deegree.datatypes.values.TypedLiteral;
072 import org.deegree.enterprise.ServiceException;
073 import org.deegree.framework.log.ILogger;
074 import org.deegree.framework.log.LoggerFactory;
075 import org.deegree.framework.util.CharsetUtils;
076 import org.deegree.framework.util.ImageUtils;
077 import org.deegree.framework.util.MimeTypeMapper;
078 import org.deegree.framework.util.NetWorker;
079 import org.deegree.framework.util.StringTools;
080 import org.deegree.framework.xml.DOMPrinter;
081 import org.deegree.framework.xml.Marshallable;
082 import org.deegree.framework.xml.XMLFragment;
083 import org.deegree.framework.xml.XSLTDocument;
084 import org.deegree.ogcwebservices.ExceptionReport;
085 import org.deegree.ogcwebservices.OGCWebService;
086 import org.deegree.ogcwebservices.OGCWebServiceException;
087 import org.deegree.ogcwebservices.OGCWebServiceRequest;
088 import org.deegree.ogcwebservices.OGCWebServiceResponse;
089 import org.deegree.ogcwebservices.wms.InvalidFormatException;
090 import org.deegree.ogcwebservices.wms.WMService;
091 import org.deegree.ogcwebservices.wms.WMServiceFactory;
092 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
093 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities_1_3_0;
094 import org.deegree.ogcwebservices.wms.configuration.WMSConfigurationType;
095 import org.deegree.ogcwebservices.wms.configuration.WMSDeegreeParams;
096 import org.deegree.ogcwebservices.wms.operation.DescribeLayerResult;
097 import org.deegree.ogcwebservices.wms.operation.GetFeatureInfo;
098 import org.deegree.ogcwebservices.wms.operation.GetFeatureInfoResult;
099 import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
100 import org.deegree.ogcwebservices.wms.operation.GetLegendGraphicResult;
101 import org.deegree.ogcwebservices.wms.operation.GetMap;
102 import org.deegree.ogcwebservices.wms.operation.GetMapResult;
103 import org.deegree.ogcwebservices.wms.operation.GetStylesResult;
104 import org.deegree.ogcwebservices.wms.operation.PutStylesResult;
105 import org.deegree.ogcwebservices.wms.operation.WMSGetCapabilitiesResult;
106 import org.deegree.owscommon.XMLFactory;
107 import org.deegree.owscommon_new.DomainType;
108 import org.deegree.owscommon_new.Operation;
109 import org.deegree.owscommon_new.OperationsMetadata;
110 import org.w3c.dom.Node;
111 import org.xml.sax.SAXException;
112
113 /**
114 * <code>WMSHandler</code> is the handler class for WMS requests and their results.
115 *
116 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
117 * @author last edited by: $Author: aschmitz $
118 *
119 * @version 2.0, $Revision: 12258 $, $Date: 2008-06-10 08:40:41 +0200 (Di, 10 Jun 2008) $
120 *
121 * @since 2.0
122 */
123 public class WMSHandler extends AbstractOWServiceHandler {
124
125 private static ILogger LOG = LoggerFactory.getLogger( WMSHandler.class );
126
127 private Color bgColor = Color.WHITE;
128
129 private HttpServletResponse resp = null;
130
131 private OGCWebServiceRequest request = null;
132
133 private String exceptionFormat;
134
135 private String format = null;
136
137 private boolean transparent = false;
138
139 private int height = 400;
140
141 private int width = 600;
142
143 private WMSConfigurationType configuration = null;
144
145 /**
146 *
147 */
148 WMSHandler() {
149 LOG.logDebug( "New WMSHandler instance created: " + this.getClass().getName() );
150 }
151
152 private String checkExceptionFormat( String exceptionFormat, List<String> availableExceptionFormats ) {
153 boolean found = false;
154 for ( String f : availableExceptionFormats ) {
155 if ( f.equalsIgnoreCase( exceptionFormat ) ) {
156 found = true;
157 }
158 }
159 if ( !found ) {
160 return availableExceptionFormats.get( 0 );
161 }
162
163 return exceptionFormat;
164 }
165
166 /**
167 * performs the passed OGCWebServiceRequest by accessing service from the pool and passing the
168 * request to it
169 */
170 public void perform( OGCWebServiceRequest request, HttpServletResponse response )
171 throws ServiceException {
172 this.request = request;
173 resp = response;
174 try {
175
176 OGCWebService service = WMServiceFactory.getService();
177 configuration = (WMSConfigurationType) ( (WMService) service ).getCapabilities();
178
179 List<String> availableExceptionFormats = new LinkedList<String>();
180
181 // add 1.1.1 names if 1.3.0 capable
182 for ( String f : configuration.getExceptions() ) {
183 if ( f.equalsIgnoreCase( "XML" ) ) {
184 availableExceptionFormats.add( "application/vnd.ogc.se_xml" );
185 }
186 if ( f.equalsIgnoreCase( "INIMAGE" ) ) {
187 availableExceptionFormats.add( "application/vnd.ogc.se_inimage" );
188 }
189 if ( f.equalsIgnoreCase( "BLANK" ) ) {
190 availableExceptionFormats.add( "application/vnd.ogc.se_blank" );
191 }
192
193 availableExceptionFormats.add( f );
194 }
195
196 // EXCEPTION HANDLING NOTES:
197 // currently, the exceptions are handled differently for each request type,
198 // change the behaviour here
199 if ( request instanceof GetMap ) {
200 GetMap req = (GetMap) request;
201 exceptionFormat = req.getExceptions();
202 exceptionFormat = checkExceptionFormat( exceptionFormat, availableExceptionFormats );
203 format = req.getFormat();
204 bgColor = req.getBGColor();
205 transparent = req.getTransparency();
206 height = req.getHeight();
207 width = req.getWidth();
208 }
209
210 if ( request instanceof GetLegendGraphic ) {
211 GetLegendGraphic req = (GetLegendGraphic) request;
212 exceptionFormat = req.getExceptions();
213 exceptionFormat = checkExceptionFormat( exceptionFormat, availableExceptionFormats );
214 format = req.getFormat();
215 height = req.getHeight();
216 width = req.getWidth();
217 }
218
219 if ( request instanceof GetFeatureInfo ) {
220 GetFeatureInfo req = (GetFeatureInfo) request;
221 exceptionFormat = req.getExceptions();
222 exceptionFormat = checkExceptionFormat( exceptionFormat, availableExceptionFormats );
223 }
224
225 if ( exceptionFormat == null || exceptionFormat.equals( "" ) ) {
226 if ( "1.1.1".equals( request.getVersion() ) ) {
227 exceptionFormat = "application/vnd.ogc.se_xml";
228 } else {
229 exceptionFormat = "XML";
230 }
231 }
232
233 // fixup the exception formats, 1.3.0 has it different
234 // note that XML/....se_xml are not the same format!
235 if ( "INIMAGE".equalsIgnoreCase( exceptionFormat ) ) {
236 exceptionFormat = "application/vnd.ogc.se_inimage";
237 }
238 if ( "BLANK".equalsIgnoreCase( exceptionFormat ) ) {
239 exceptionFormat = "application/vnd.ogc.se_blank";
240 }
241
242 if ( service == null ) {
243 writeServiceExceptionReport( new OGCWebServiceException( "WMS", "could not access a WMService instance" ) );
244 return;
245 }
246
247 // first, try the normal case
248 Object o = service.doService( request );
249 handleResponse( o );
250
251 } catch ( OGCWebServiceException e ) {
252 writeServiceExceptionReport( e );
253 }
254 }
255
256 /**
257 *
258 *
259 * @param result
260 * @throws OGCWebServiceException
261 */
262 private void handleResponse( Object result ) {
263 // this method may need restructuring
264
265 // handle exception case
266 if ( result instanceof OGCWebServiceException ) {
267 writeServiceExceptionReport( (OGCWebServiceException) result );
268 return;
269 }
270
271 try {
272 OGCWebServiceResponse response = (OGCWebServiceResponse) result;
273
274 if ( response.getException() != null ) {
275 // handle the case that an exception occured during the
276 // request performance
277 writeServiceExceptionReport( response.getException() );
278 } else {
279 if ( response instanceof OGCWebServiceException ) {
280 writeServiceExceptionReport( (OGCWebServiceException) response );
281 } else if ( response instanceof Exception ) {
282 sendException( resp, (Exception) response );
283 } else if ( response instanceof WMSGetCapabilitiesResult ) {
284 handleGetCapabilitiesResponse( (WMSGetCapabilitiesResult) response );
285 } else if ( response instanceof GetMapResult ) {
286 handleGetMapResponse( (GetMapResult) response );
287 } else if ( response instanceof GetFeatureInfoResult ) {
288 handleFeatureInfoResponse( (GetFeatureInfoResult) response );
289 } else if ( response instanceof GetStylesResult ) {
290 handleGetStylesResponse( (GetStylesResult) response );
291 } else if ( response instanceof PutStylesResult ) {
292 handlePutStylesResponse( (PutStylesResult) response );
293 } else if ( response instanceof DescribeLayerResult ) {
294 handleDescribeLayerResponse( (DescribeLayerResult) response );
295 } else if ( response instanceof GetLegendGraphicResult ) {
296 handleGetLegendGraphicResponse( (GetLegendGraphicResult) response );
297 }
298 }
299 } catch ( InvalidFormatException ife ) {
300 LOG.logError( ife.getMessage(), ife );
301 writeServiceExceptionReport( ife );
302 } catch ( Exception e ) {
303 LOG.logError( e.getMessage(), e );
304 writeServiceExceptionReport( new OGCWebServiceException( "WMS:write", e.getLocalizedMessage() ) );
305 }
306 }
307
308 /**
309 * handles the response to a get capabilities request
310 *
311 * @param response
312 * @throws IOException
313 * @throws TransformerException
314 */
315 private void handleGetCapabilitiesResponse( WMSGetCapabilitiesResult response )
316 throws IOException, TransformerException {
317 WMSConfigurationType capa = response.getCapabilities();
318
319 WMSDeegreeParams params = capa.getDeegreeParams();
320
321 // version war follows
322
323 boolean version130 = "1.3.0".equals( capa.calculateVersion( request.getVersion() ) );
324
325 // version not set -> use highest supported version
326 // use request's version otherwise
327
328 boolean support111 = false;
329 boolean support130 = false;
330 for ( String version : params.getSupportedVersions() ) {
331 if ( "1.1.1".equals( version ) )
332 support111 = true;
333 if ( "1.3.0".equals( version ) )
334 support130 = true;
335 }
336
337 if ( ( !support130 ) && ( !support111 ) ) {
338 support111 = true;
339 }
340
341 if ( version130 && support130 ) {
342 resp.setContentType( "text/xml" );
343 } else {
344 resp.setContentType( "application/vnd.ogc.wms_xml" );
345 }
346
347 XMLFragment doc = null;
348
349 if ( ( ( ( !version130 ) && support111 ) || ( !support130 ) ) && ( capa instanceof WMSCapabilities_1_3_0 ) ) {
350 doc = org.deegree.ogcwebservices.wms.XMLFactory.exportAs_1_1_1( (WMSCapabilities_1_3_0) capa );
351 } else {
352 doc = org.deegree.ogcwebservices.wms.XMLFactory.export( (WMSCapabilities) capa );
353 }
354
355 if ( ( version130 && support130 ) || ( !support111 ) ) {
356 doc.getRootElement().setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
357 doc.getRootElement().setAttribute(
358 "xsi:schemaLocation",
359 "http://www.opengis.net/wms "
360 + "http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd"
361 + " http://www.opengis.net/sld "
362 + "http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd" );
363
364 doc.prettyPrint( resp.getWriter() );
365 } else {
366 String xml = new XMLFragment( doc.getRootElement() ).getAsString();
367 xml = doc.getAsString();
368 String dtd = NetWorker.url2String( configuration.getDeegreeParams().getDTDLocation() );
369 StringBuffer sb = new StringBuffer();
370 sb.append( "<!DOCTYPE WMT_MS_Capabilities SYSTEM " );
371 sb.append( "'" + dtd + "' \n" );
372 sb.append( "[\n<!ELEMENT VendorSpecificCapabilities EMPTY>\n]>" );
373
374 int p = xml.indexOf( "?>" );
375 if ( p > -1 ) {
376 xml = xml.substring( p + 2, xml.length() );
377 }
378
379 xml = StringTools.concat( 50000, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "\n", sb.toString(), xml );
380
381 xml = StringTools.replace( xml, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"", "", false );
382
383 try {
384 PrintWriter pw = resp.getWriter();
385 pw.print( xml );
386 pw.close();
387 } catch ( Exception e ) {
388 LOG.logError( "-", e );
389 }
390
391 }
392 }
393
394 /**
395 * handles the response to a get map request
396 *
397 * @param response
398 */
399 private void handleGetMapResponse( GetMapResult response )
400 throws InvalidFormatException {
401 // schmitz: added the toLowerCase to avoid errors
402 String mime = MimeTypeMapper.toMimeType( ( (GetMap) request ).getFormat().toLowerCase() );
403
404 if ( !MimeTypeMapper.isImageType( mime ) ) {
405 throw new InvalidFormatException( mime + " is not a known image format" );
406 }
407
408 writeImage( response.getMap(), mime );
409 }
410
411 /**
412 * handles the response to a get featureinfo request
413 *
414 * @param response
415 */
416 private void handleFeatureInfoResponse( GetFeatureInfoResult response )
417 throws Exception {
418 GetFeatureInfo req = (GetFeatureInfo) request;
419
420 String s = req.getInfoFormat();
421
422 // check if GML is actually the correct one
423 // THIS IS A HACK
424 if ( req.isInfoFormatDefault() ) {
425 OperationsMetadata om = configuration.getOperationMetadata();
426 Operation op = om.getOperation( new QualifiedName( "GetFeatureInfo" ) );
427 DomainType dt = (DomainType) op.getParameter( new QualifiedName( "Format" ) );
428 List<TypedLiteral> vals = dt.getValues();
429 s = vals.get( 0 ).getValue();
430 }
431
432 String mime = MimeTypeMapper.toMimeType( s );
433 resp.setContentType( mime + "; charset=" + CharsetUtils.getSystemCharset() );
434
435 String fir = response.getFeatureInfo();
436
437 String filter = FeatureInfoFilterDef.getString( s );
438
439 if ( filter != null ) {
440 handleFilteredFeatureInfoResponse( fir, filter );
441 } else {
442 OutputStreamWriter os = null;
443 try {
444 os = new OutputStreamWriter( resp.getOutputStream(), CharsetUtils.getSystemCharset() );
445 os.write( fir );
446 } catch ( Exception e ) {
447 LOG.logError( "could not write to outputstream", e );
448 } finally {
449 os.close();
450 }
451 }
452 }
453
454 /**
455 * @param fir
456 * @param filter
457 * @throws MalformedURLException
458 * @throws SAXException
459 * @throws IOException
460 * @throws URISyntaxException
461 * @throws TransformerException
462 */
463 private void handleFilteredFeatureInfoResponse( String fir, String filter )
464 throws Exception {
465 URL url = new URL( configuration.getBaseURL(), filter );
466 LOG.logDebug( "used XSLT for transformation: ", url );
467 LOG.logDebug( "GML document to transform", fir );
468 if ( url != null ) {
469 Source xmlSource = new StreamSource( new StringReader( fir ) );
470 Source xslSource;
471 try {
472 xslSource = new StreamSource( url.openStream() );
473 } catch ( IOException ioe ) {
474 throw new InvalidFormatException( "Unknown feature info format (missing XSL script in configuration?)." );
475 }
476 OutputStream os = null;
477 try {
478 os = resp.getOutputStream();
479 StreamResult result = new StreamResult( os );
480 XSLTDocument.transform( xmlSource, xslSource, result, null, null );
481 } catch ( IOException e ) {
482 LOG.logError( "could not write to outputstream", e );
483 } finally {
484 os.close();
485 }
486 }
487 }
488
489 /**
490 * handles the response to a get styles request
491 *
492 * @param response
493 */
494 private void handleGetStylesResponse( GetStylesResult response ) {
495 throw new RuntimeException( "method: handleGetStylesResponse not implemented yet" );
496 }
497
498 /**
499 * handles the response to a put styles request
500 *
501 * @param response
502 */
503 private void handlePutStylesResponse( PutStylesResult response ) {
504 throw new RuntimeException( "method: handlePutStylesResponse not implemented yet" );
505 }
506
507 /**
508 * handles the response to a describe layer request
509 *
510 * @param response
511 * @throws IOException
512 * @throws TransformerException
513 */
514 private void handleDescribeLayerResponse( DescribeLayerResult response )
515 throws TransformerException, IOException {
516 resp.setCharacterEncoding( "UTF-8" );
517 Writer out = resp.getWriter();
518 response.getResult().prettyPrint( out );
519 out.close();
520 }
521
522 /**
523 * handles the response to a get legend graphic request
524 *
525 * @param response
526 */
527 private void handleGetLegendGraphicResponse( GetLegendGraphicResult response )
528 throws Exception {
529 String mime = MimeTypeMapper.toMimeType( ( (GetLegendGraphic) request ).getFormat() );
530
531 if ( !MimeTypeMapper.isImageType( mime ) ) {
532 throw new InvalidFormatException( mime + " is not a known image format" );
533 }
534
535 writeImage( response.getLegendGraphic(), mime );
536 }
537
538 private void writeServiceExceptionReport( OGCWebServiceException exception, OutputStream out ) {
539 LOG.logInfo( "Sending exception in XML format." );
540 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
541 ExceptionReport report = new ExceptionReport( new OGCWebServiceException[] { exception } );
542 String msg;
543 if ( exceptionFormat.equals( "XML" ) ) {
544 msg = XMLFactory.exportNS( report ).getAsPrettyString();
545 } else {
546 msg = XMLFactory.export( report ).getAsPrettyString();
547 }
548
549 LOG.logDebug( "Exception being sent: " + msg );
550 }
551
552 ExceptionReport report = new ExceptionReport( new OGCWebServiceException[] { exception } );
553 try {
554 XMLFragment doc;
555
556 if ( exceptionFormat.equals( "XML" ) ) {
557 resp.setContentType( "text/xml" );
558 doc = XMLFactory.exportNS( report );
559 } else {
560 resp.setContentType( "application/vnd.ogc.se_xml" );
561 doc = XMLFactory.export( report );
562 }
563
564 doc.write( out );
565 out.close();
566 } catch ( Exception ex ) {
567 LOG.logError( "ERROR: " + ex.getMessage(), ex );
568 }
569 }
570
571 /**
572 * writes an service exception report into the <tt>OutputStream</tt> back to the client. the
573 * method considers the format an exception shall be returned to the client as defined in the
574 * request.
575 *
576 * @param exception
577 * the exception object containing the code and message
578 * @throws OGCWebServiceException
579 */
580 private void writeServiceExceptionReport( OGCWebServiceException exception ) {
581 String code = "none";
582 if ( exception.getCode() != null ) {
583 code = exception.getCode().value;
584 }
585 String message = exception.getMessage();
586
587 LOG.logInfo( "sending exception in format " + exceptionFormat );
588 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
589 ExceptionReport report = new ExceptionReport( new OGCWebServiceException[] { exception } );
590 String msg;
591 if ( exceptionFormat.equals( "XML" ) ) {
592 msg = XMLFactory.exportNS( report ).getAsPrettyString();
593 } else {
594 msg = XMLFactory.export( report ).getAsPrettyString();
595 }
596
597 LOG.logDebug( "Exception being sent: " + msg );
598 }
599
600 if ( exceptionFormat.equals( "application/vnd.ogc.se_inimage" ) ) {
601 BufferedImage bi = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
602 Graphics g = bi.getGraphics();
603
604 if ( !transparent ) {
605 g.setColor( bgColor );
606 g.fillRect( 0, 0, bi.getWidth(), bi.getHeight() );
607 }
608
609 g.setColor( Color.BLUE );
610 g.drawString( code, 5, 20 );
611 int pos1 = message.indexOf( ':' );
612 g.drawString( message.substring( 0, pos1 + 1 ), 5, 50 );
613 g.drawString( message.substring( pos1 + 1, message.length() ), 5, 80 );
614 String mime = MimeTypeMapper.toMimeType( format );
615 writeImage( bi, mime );
616 } else if ( exceptionFormat.equals( "application/vnd.ogc.se_blank" ) ) {
617 BufferedImage bi = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
618 Graphics g = bi.getGraphics();
619
620 if ( !transparent ) {
621 g.setColor( bgColor );
622 g.fillRect( 0, 0, bi.getWidth(), bi.getHeight() );
623 }
624
625 g.dispose();
626 String mime = MimeTypeMapper.toMimeType( format );
627 writeImage( bi, mime );
628 } else {
629 LOG.logInfo( "Sending OGCWebServiceException to client." );
630 ExceptionReport report = new ExceptionReport( new OGCWebServiceException[] { exception } );
631 try {
632 XMLFragment doc;
633
634 if ( exceptionFormat.equals( "XML" ) ) {
635 resp.setContentType( "text/xml" );
636 doc = XMLFactory.exportNS( report );
637 } else {
638 resp.setContentType( "application/vnd.ogc.se_xml" );
639 doc = XMLFactory.export( report );
640 }
641
642 OutputStream os = resp.getOutputStream();
643 doc.write( os );
644 os.close();
645 } catch ( Exception ex ) {
646 LOG.logError( "ERROR: " + ex.getMessage(), ex );
647 }
648 }
649 }
650
651 /**
652 * writes the passed image to the response output stream.
653 *
654 * @param output
655 * @param mime
656 */
657 private void writeImage( Object output, String mime ) {
658 OutputStream os = null;
659 try {
660 resp.setContentType( mime );
661 if ( mime.equalsIgnoreCase( "image/gif" ) ) {
662 BufferedImage img = (BufferedImage) output;
663 ByteArrayOutputStream out = new ByteArrayOutputStream( img.getWidth() * img.getHeight() * 4 );
664 try {
665 ImageUtils.encodeGif( out, img );
666 } catch ( IOException e ) {
667 LOG.logWarning( "ACME failed to write GIF image, trying ImageIO." );
668 LOG.logDebug( "Stack trace", e );
669 // use imageio, it can transform the colors correctly starting from Java 1.6
670 if ( !write( img, "gif", out ) ) {
671 os = resp.getOutputStream();
672 writeServiceExceptionReport( new OGCWebServiceException( e.getLocalizedMessage() ), os );
673 os.close();
674 return;
675 }
676 }
677
678 resp.setContentType( mime );
679 os = resp.getOutputStream();
680
681 out.close();
682 byte[] bs = out.toByteArray();
683 out = null;
684
685 os.write( bs );
686 } else if ( mime.equalsIgnoreCase( "image/jpg" ) || mime.equalsIgnoreCase( "image/jpeg" ) ) {
687 os = resp.getOutputStream();
688 ImageUtils.saveImage( (BufferedImage) output, os, "jpeg",
689 configuration.getDeegreeParams().getMapQuality() );
690 } else if ( mime.equalsIgnoreCase( "image/png" ) ) {
691 os = resp.getOutputStream();
692 ImageUtils.saveImage( (BufferedImage) output, os, "png", 1 );
693 } else if ( mime.equalsIgnoreCase( "image/tif" ) || mime.equalsIgnoreCase( "image/tiff" ) ) {
694 os = resp.getOutputStream();
695 ImageUtils.saveImage( (BufferedImage) output, os, "tif", 1 );
696 } else if ( mime.equalsIgnoreCase( "image/bmp" ) ) {
697 os = resp.getOutputStream();
698 ImageUtils.saveImage( (BufferedImage) output, os, "bmp", 1 );
699 } else if ( mime.equalsIgnoreCase( "image/svg+xml" ) ) {
700 os = resp.getOutputStream();
701 resp.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() );
702 PrintWriter pw = new PrintWriter( os );
703 DOMPrinter.printNode( pw, (Node) output );
704 pw.close();
705 } else {
706 resp.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() );
707 os = resp.getOutputStream();
708 OGCWebServiceException exce = new OGCWebServiceException( "WMS:writeImage",
709 "unsupported image format: " + mime );
710 os.write( ( (Marshallable) exce ).exportAsXML().getBytes() );
711 }
712
713 os.close();
714 } catch ( Exception e ) {
715 LOG.logError( resp.isCommitted() ? "Response is already committed!" : "Response is not committed yet." );
716 LOG.logError( "Error while writing image: ", e );
717 writeServiceExceptionReport( new OGCWebServiceException( e.getLocalizedMessage() ), os );
718 }
719 }
720
721 }