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