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