001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/wms/RemoteWMService.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 package org.deegree.ogcwebservices.wms;
037
038 import static org.deegree.enterprise.WebUtils.enableProxyUsage;
039 import static org.deegree.framework.util.MapUtils.DEFAULT_PIXEL_SIZE;
040 import static org.deegree.framework.util.MapUtils.calcScale;
041 import static org.deegree.model.spatialschema.GeometryFactory.createEnvelope;
042 import static org.deegree.ogcwebservices.OWSUtils.validateHTTPGetBaseURL;
043
044 import java.awt.image.BufferedImage;
045 import java.io.IOException;
046 import java.io.InputStream;
047 import java.io.StringReader;
048 import java.net.MalformedURLException;
049 import java.net.URL;
050 import java.util.HashMap;
051 import java.util.HashSet;
052 import java.util.Iterator;
053 import java.util.LinkedList;
054 import java.util.List;
055 import java.util.Properties;
056
057 import javax.imageio.ImageIO;
058 import javax.media.jai.JAI;
059 import javax.media.jai.RenderedOp;
060
061 import org.apache.commons.httpclient.Header;
062 import org.apache.commons.httpclient.HttpClient;
063 import org.apache.commons.httpclient.HttpException;
064 import org.apache.commons.httpclient.methods.GetMethod;
065 import org.deegree.datatypes.QualifiedName;
066 import org.deegree.framework.log.ILogger;
067 import org.deegree.framework.log.LoggerFactory;
068 import org.deegree.framework.util.BootLogger;
069 import org.deegree.framework.util.CharsetUtils;
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.XMLFragment;
074 import org.deegree.i18n.Messages;
075 import org.deegree.model.crs.CRSFactory;
076 import org.deegree.model.crs.CRSTransformationException;
077 import org.deegree.model.crs.CoordinateSystem;
078 import org.deegree.model.crs.GeoTransformer;
079 import org.deegree.model.crs.UnknownCRSException;
080 import org.deegree.model.spatialschema.Envelope;
081 import org.deegree.ogcwebservices.OGCWebService;
082 import org.deegree.ogcwebservices.OGCWebServiceException;
083 import org.deegree.ogcwebservices.OGCWebServiceRequest;
084 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
085 import org.deegree.ogcwebservices.wms.capabilities.Layer;
086 import org.deegree.ogcwebservices.wms.capabilities.LayerBoundingBox;
087 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
088 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
089 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory;
090 import org.deegree.ogcwebservices.wms.operation.DescribeLayer;
091 import org.deegree.ogcwebservices.wms.operation.GetFeatureInfo;
092 import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
093 import org.deegree.ogcwebservices.wms.operation.GetMap;
094 import org.deegree.ogcwebservices.wms.operation.GetStyles;
095 import org.deegree.ogcwebservices.wms.operation.PutStyles;
096 import org.deegree.ogcwebservices.wms.operation.WMSGetCapabilities;
097 import org.deegree.ogcwebservices.wms.operation.WMSProtocolFactory;
098 import org.deegree.owscommon_new.DCP;
099 import org.deegree.owscommon_new.HTTP;
100 import org.deegree.owscommon_new.Operation;
101 import org.deegree.owscommon_new.OperationsMetadata;
102 import org.xml.sax.SAXException;
103
104 import com.sun.media.jai.codec.MemoryCacheSeekableStream;
105
106 /**
107 * An instance of the class acts as a wrapper to a remote WMS.
108 *
109 * @version $Revision: 18195 $
110 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
111 */
112 public class RemoteWMService implements OGCWebService {
113
114 private static ILogger LOG = LoggerFactory.getLogger( RemoteWMService.class );
115
116 private static final String GETCAPABILITIES_NAME = "GetCapabilities";
117
118 private static final String CAPABILITIES_NAME = "Capabilities";
119
120 private static final String GETMAP_NAME = "GetMap";
121
122 private static final String MAP_NAME = "Map";
123
124 private static final String GETFEATUREINFO_NAME = "GetFeatureInfo";
125
126 private static final String FEATUREINFO_NAME = "FeatureInfo";
127
128 private static final String DESCRIBELAYER_NAME = "DescribeLayer";
129
130 private static final String GETLEGENDGRAPHIC_NAME = "GetLegendGraphic";
131
132 private static final String GETSTYLES_NAME = "GetStyles";
133
134 private static final String PUTSTYLES_NAME = "PutStyles";
135
136 // private static final String UNKNOWN_NAME = "Unknown";
137
138 protected HashMap<String, URL> addresses = null;
139
140 protected WMSCapabilities capabilities = null;
141
142 private static Properties properties;
143 static {
144 if ( properties == null ) {
145 try {
146 properties = new Properties();
147 InputStream is = RemoteWMService.class.getResourceAsStream( "remotewmservice.properties" );
148 properties.load( is );
149 is.close();
150 } catch ( Exception e ) {
151 BootLogger.logError( e.getMessage(), e );
152 }
153 }
154 }
155
156 /**
157 * Creates a new instance of RemoteWMService
158 *
159 * @param capabilities
160 */
161 public RemoteWMService( WMSCapabilities capabilities ) {
162 this.capabilities = capabilities;
163 addresses = new HashMap<String, URL>();
164
165 // get GetCapabilities operation address
166 List<DCP> dcps = null;
167 HTTP http = null;
168
169 OperationsMetadata om = capabilities.getOperationMetadata();
170
171 if ( capabilities.getVersion().equals( "1.0.0" ) ) {
172 dcps = om.getOperation( new QualifiedName( CAPABILITIES_NAME ) ).getDCP();
173 for ( DCP dcp : dcps )
174 if ( dcp instanceof HTTP )
175 http = (HTTP) dcp;
176 if ( http != null ) {
177 addresses.put( CAPABILITIES_NAME, http.getLinks().get( 0 ).getLinkage().getHref() );
178 }
179 } else {
180 dcps = om.getOperation( new QualifiedName( GETCAPABILITIES_NAME ) ).getDCP();
181 for ( DCP dcp : dcps )
182 if ( dcp instanceof HTTP )
183 http = (HTTP) dcp;
184 if ( http != null ) {
185 addresses.put( GETCAPABILITIES_NAME, http.getLinks().get( 0 ).getLinkage().getHref() );
186 }
187 }
188
189 // get GetMap operation address
190 if ( capabilities.getVersion().equals( "1.0.0" ) ) {
191 dcps = om.getOperation( new QualifiedName( MAP_NAME ) ).getDCP();
192 for ( DCP dcp : dcps )
193 if ( dcp instanceof HTTP )
194 http = (HTTP) dcp;
195 if ( http != null ) {
196 addresses.put( MAP_NAME, http.getLinks().get( 0 ).getLinkage().getHref() );
197 }
198 } else {
199 dcps = om.getOperation( new QualifiedName( GETMAP_NAME ) ).getDCP();
200 for ( DCP dcp : dcps )
201 if ( dcp instanceof HTTP )
202 http = (HTTP) dcp;
203 if ( http != null ) {
204 addresses.put( GETMAP_NAME, http.getLinks().get( 0 ).getLinkage().getHref() );
205 }
206 }
207
208 // get GetFeatureInfo operation address
209 if ( capabilities.getVersion().equals( "1.0.0" ) ) {
210 Operation operation = om.getOperation( new QualifiedName( FEATUREINFO_NAME ) );
211
212 if ( operation != null ) {
213 dcps = operation.getDCP();
214 for ( DCP dcp : dcps )
215 if ( dcp instanceof HTTP )
216 http = (HTTP) dcp;
217 if ( http != null ) {
218 addresses.put( FEATUREINFO_NAME, http.getLinks().get( 0 ).getLinkage().getHref() );
219 }
220 }
221 } else {
222 Operation operation = om.getOperation( new QualifiedName( GETFEATUREINFO_NAME ) );
223
224 if ( operation != null ) {
225 dcps = operation.getDCP();
226 for ( DCP dcp : dcps )
227 if ( dcp instanceof HTTP )
228 http = (HTTP) dcp;
229 if ( http != null ) {
230 addresses.put( GETFEATUREINFO_NAME, http.getLinks().get( 0 ).getLinkage().getHref() );
231 }
232 }
233 }
234
235 // get GetLegendGraphic operation address
236 Operation operation = om.getOperation( new QualifiedName( GETLEGENDGRAPHIC_NAME ) );
237
238 if ( operation != null ) {
239 dcps = operation.getDCP();
240 for ( DCP dcp : dcps )
241 if ( dcp instanceof HTTP )
242 http = (HTTP) dcp;
243 if ( http != null ) {
244 addresses.put( GETLEGENDGRAPHIC_NAME, http.getLinks().get( 0 ).getLinkage().getHref() );
245 }
246 }
247
248 // get GetStyles operation address
249 operation = om.getOperation( new QualifiedName( GETSTYLES_NAME ) );
250
251 if ( operation != null ) {
252 dcps = operation.getDCP();
253 for ( DCP dcp : dcps )
254 if ( dcp instanceof HTTP )
255 http = (HTTP) dcp;
256 if ( http != null ) {
257 addresses.put( GETSTYLES_NAME, http.getLinks().get( 0 ).getLinkage().getHref() );
258 }
259 }
260
261 // get PutStyles operation address
262 operation = om.getOperation( new QualifiedName( PUTSTYLES_NAME ) );
263
264 if ( operation != null ) {
265 dcps = operation.getDCP();
266 for ( DCP dcp : dcps )
267 if ( dcp instanceof HTTP )
268 http = (HTTP) dcp;
269 if ( http != null ) {
270 addresses.put( PUTSTYLES_NAME, http.getLinks().get( 0 ).getLinkage().getHref() );
271 }
272 }
273
274 // get DescribeLayer operation address
275 operation = om.getOperation( new QualifiedName( DESCRIBELAYER_NAME ) );
276
277 if ( operation != null ) {
278 dcps = operation.getDCP();
279 for ( DCP dcp : dcps )
280 if ( dcp instanceof HTTP )
281 http = (HTTP) dcp;
282 if ( http != null ) {
283 addresses.put( DESCRIBELAYER_NAME, http.getLinks().get( 0 ).getLinkage().getHref() );
284 }
285 }
286
287 }
288
289 public OGCCapabilities getCapabilities() {
290 return capabilities;
291 }
292
293 private HashSet<CoordinateSystem> getSupportedCoordinateSystems( GetMap getMap )
294 throws UnknownCRSException {
295 HashSet<CoordinateSystem> crs = new HashSet<CoordinateSystem>();
296 List<Layer> layers = new LinkedList<Layer>();
297 for ( GetMap.Layer l : getMap.getLayers() ) {
298 if ( l == null ) {
299 continue; // unclear when/why this can happen
300 }
301 Layer lay = capabilities.getLayer( l.getName() );
302 while ( lay.getParent() != null ) {
303 layers.add( lay );
304 lay = lay.getParent();
305 }
306 }
307 for ( Layer l : layers ) {
308 for ( LayerBoundingBox bbox : l.getBoundingBoxes() ) {
309 if ( bbox.getCoordinateSystem() != null ) {
310 crs.add( bbox.getCoordinateSystem() );
311 }
312 }
313 for ( String srs : l.getSrs() ) {
314 crs.add( CRSFactory.create( srs ) );
315 }
316 }
317 return crs;
318 }
319
320 /**
321 * the method performs the handling of the passed OGCWebServiceEvent directly and returns the result to the calling
322 * class/method
323 *
324 * @param request
325 * request (WMS, WCS, WFS, WCAS, WCTS, WTS, Gazetter) to perform
326 *
327 * @throws OGCWebServiceException
328 */
329 public Object doService( OGCWebServiceRequest request )
330 throws OGCWebServiceException {
331 Object o = null;
332 if ( request instanceof GetMap ) {
333 o = handleGetMap( (GetMap) request );
334 o = WMSProtocolFactory.createGetMapResponse( request, null, o );
335 } else if ( request instanceof GetFeatureInfo ) {
336 o = handleFeatureInfo( (GetFeatureInfo) request );
337 o = WMSProtocolFactory.createGetFeatureInfoResponse( request, null, (String) o );
338 } else if ( request instanceof GetLegendGraphic ) {
339 o = handleGetLegendGraphic( (GetLegendGraphic) request );
340 o = WMSProtocolFactory.createGetLegendGraphicResponse( request, o );
341 }
342 /*
343 * else if ( request instanceof WMSGetCapabilities) { handleGetCapabilities( (WMSGetCapabilities)request, client
344 * ); } else if ( request instanceof GetStyles ) { handleGetStyles( (GetStyles)request, client ); } else if (
345 * request instanceof PutStyles ) { handlePutStyles( (PutStyles)request, client ); } else if ( request
346 * instanceof DescribeLayer ) { handleDescribeLayer( (DescribeLayer)request, client ); } else if ( request
347 * instanceof GetLegendGraphic ) { handleGetLegendGraphic( (GetLegendGraphic)request, client ); }
348 */
349
350 return o;
351
352 }
353
354 // checks for excessive &
355 private static String constructRequestURL( String params, String url ) {
356 if ( url.endsWith( "?" ) && params.startsWith( "&" ) ) {
357 return url + params.substring( 1 );
358 }
359
360 return url + params;
361 }
362
363 /**
364 * performs a GetMap request against the remote service. The result contains the map decoded in the desired format
365 * as a byte array.
366 *
367 * @param request
368 * GetMap request
369 * @return the requested map-image
370 * @throws OGCWebServiceException
371 * if the url in the request is <code>null</code>
372 */
373 protected Object handleGetMap( GetMap request )
374 throws OGCWebServiceException {
375
376 URL url = null;
377
378 if ( request.getVersion().equals( "1.0.0" ) ) {
379 url = addresses.get( MAP_NAME );
380 } else {
381 url = addresses.get( GETMAP_NAME );
382 }
383
384 try {
385 Envelope requestBBOX = request.getBoundingBox();
386 HashSet<CoordinateSystem> crss = getSupportedCoordinateSystems( request );
387 CoordinateSystem requestCRS = CRSFactory.create( request.getSrs() );
388 requestBBOX = createEnvelope( requestBBOX.getMin(), requestBBOX.getMax(), requestCRS );
389 if ( !crss.contains( requestCRS ) ) {
390 Iterator<CoordinateSystem> iterator = crss.iterator();
391 CoordinateSystem dataCRS = iterator.hasNext() ? iterator.next() : null;
392 if ( dataCRS != null ) {
393 GeoTransformer transformer = new GeoTransformer( dataCRS );
394 GeoTransformer transformBack = new GeoTransformer( requestCRS );
395 Envelope dataBBOX = transformer.transform( requestBBOX, requestCRS, true );
396
397 int origWidth = request.getWidth();
398 int origHeight = request.getHeight();
399
400 double scale = calcScale( origWidth, origHeight, requestBBOX, requestCRS, DEFAULT_PIXEL_SIZE );
401 double newScale = calcScale( origWidth, origHeight, dataBBOX, dataCRS, DEFAULT_PIXEL_SIZE );
402 double ratio = scale / newScale;
403
404 LOG.logDebug( "Requesting transformed bounding box " + dataBBOX + " in srs "
405 + dataCRS.getIdentifier() );
406 request.setBoundingBox( dataBBOX );
407 request.setSrs( dataCRS.getIdentifier() );
408 request.setWidth( (int) ( origWidth * ratio ) );
409 request.setHeight( (int) ( origHeight * ratio ) );
410 Object o = handleGetMap( request );
411 if ( o instanceof BufferedImage ) {
412 return transformBack.transform( (BufferedImage) o, dataBBOX, requestBBOX, origWidth,
413 origHeight, 16, 3, null );
414 }
415
416 return o;
417 }
418 }
419 } catch ( UnknownCRSException e ) {
420 LOG.logError( e.getLocalizedMessage(), e );
421 } catch ( CRSTransformationException e ) {
422 LOG.logError( "An error occurred while transforming bounding boxes (this should not happen)", e );
423 }
424
425 String us = constructRequestURL( request.getRequestParameter(), validateHTTPGetBaseURL( url.toExternalForm() ) );
426
427 LOG.logDebug( "remote wms getmap", us );
428
429 if ( capabilities.getVersion().compareTo( "1.0.0" ) <= 0 ) {
430 us = StringTools.replace( us, "TRANSPARENCY", "TRANSPARENT", false );
431 us = StringTools.replace( us, "GetMap", "map", false );
432 us = StringTools.replace( us, "image/", "", false );
433 }
434
435 Object result = null;
436 try {
437 HttpClient client = new HttpClient();
438 enableProxyUsage( client, new URL( us ) );
439 int timeout = 25000;
440 if ( properties != null && properties.getProperty( "timeout" ) != null ) {
441 timeout = Integer.parseInt( properties.getProperty( "timeout" ) );
442 }
443 LOG.logDebug( "timeout is:", timeout );
444 client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
445 GetMethod get = new GetMethod( us );
446 client.executeMethod( get );
447 InputStream is = get.getResponseBodyAsStream();
448 Header header = get.getResponseHeader( "Content-type" );
449
450 String contentType = header.getValue();
451 String[] tmp = StringTools.toArray( contentType, ";", true );
452 for ( int i = 0; i < tmp.length; i++ ) {
453 if ( tmp[i].indexOf( "image" ) > -1 ) {
454 contentType = tmp[i];
455 break;
456 }
457 contentType = tmp[0];
458 }
459
460 if ( MimeTypeMapper.isImageType( contentType ) && MimeTypeMapper.isKnownImageType( contentType ) ) {
461 MemoryCacheSeekableStream mcss = new MemoryCacheSeekableStream( is );
462 RenderedOp rop = JAI.create( "stream", mcss );
463 result = rop.getAsBufferedImage();
464 mcss.close();
465 } else {
466 // extract remote (error) message if the response
467 // contains a known mime type
468 String res = "";
469 if ( MimeTypeMapper.isKnownMimeType( contentType ) ) {
470 res = "Remote-WMS message: " + getInputStreamContent( is );
471 } else {
472 res = Messages.getMessage( "REMOTEWMS_GETMAP_INVALID_RESULT", contentType, us );
473 }
474 throw new OGCWebServiceException( "RemoteWMS:handleGetMap", res );
475 }
476 } catch ( HttpException e ) {
477 LOG.logError( e.getMessage(), e );
478 String msg = Messages.getMessage( "REMOTEWMS_GETMAP_GENERAL_ERROR",
479 capabilities.getServiceIdentification().getTitle(), us );
480 throw new OGCWebServiceException( "RemoteWMS:handleGetMap", msg );
481 } catch ( IOException e ) {
482 LOG.logError( e.getMessage(), e );
483 String msg = Messages.getMessage( "REMOTEWMS_GETMAP_GENERAL_ERROR",
484 capabilities.getServiceIdentification().getTitle(), us );
485 throw new OGCWebServiceException( "RemoteWMS:handleGetMap", msg );
486 }
487 // catch ( Exception e ) {
488 // LOG.logError( e.getMessage(), e );
489 // String msg = Messages.getMessage( "REMOTEWMS_GETMAP_GENERAL_ERROR",
490 // capabilities.getServiceIdentification().getTitle(), us );
491 // throw new OGCWebServiceException( "RemoteWMS:handleGetMap", msg );
492 // }
493
494 return result;
495 }
496
497 /**
498 * reads feature infos from the remote WMS by performing a FeatureInfo request against it. As long the result of a
499 * FeatureInfo request is generic (for usual it is som HTML) it isn't easy to combine the result with that of other
500 * WMS's
501 *
502 * @param request
503 * feature info request
504 * @return the response of the GetFeatureInfo request.
505 * @throws OGCWebServiceException
506 * if the request could not be excuted correctly.
507 */
508 protected Object handleFeatureInfo( GetFeatureInfo request )
509 throws OGCWebServiceException {
510
511 URL url = null;
512
513 if ( request.getVersion().equals( "1.0.0" ) ) {
514 url = addresses.get( FEATUREINFO_NAME );
515 } else {
516 url = addresses.get( GETFEATUREINFO_NAME );
517 }
518
519 if ( url == null ) {
520 String msg = Messages.getMessage( "REMOTEWMS_GFI_NOT_SUPPORTED",
521 capabilities.getServiceIdentification().getTitle() );
522 throw new OGCWebServiceException( msg );
523 }
524
525 try {
526 GetMap gm = request.getGetMapRequestCopy();
527 Envelope requestBBOX = gm.getBoundingBox();
528 HashSet<CoordinateSystem> crss = getSupportedCoordinateSystems( gm );
529 CoordinateSystem requestCRS = CRSFactory.create( gm.getSrs() );
530 if ( !crss.contains( requestCRS ) ) {
531 CoordinateSystem dataCRS = crss.iterator().next();
532 if ( dataCRS != null ) {
533 GeoTransformer transformer = new GeoTransformer( dataCRS );
534 GeoTransformer transformBack = new GeoTransformer( requestCRS );
535 Envelope dataBBOX = transformer.transform( requestBBOX, requestCRS, true );
536
537 int origWidth = gm.getWidth();
538 int origHeight = gm.getHeight();
539
540 double scale = calcScale( origWidth, origHeight, requestBBOX, requestCRS, DEFAULT_PIXEL_SIZE );
541 double newScale = calcScale( origWidth, origHeight, dataBBOX, dataCRS, DEFAULT_PIXEL_SIZE );
542 double ratio = scale / newScale;
543
544 LOG.logDebug( "Requesting transformed bounding box " + dataBBOX + " in srs "
545 + dataCRS.getIdentifier() );
546 gm.setBoundingBox( dataBBOX );
547 gm.setSrs( dataCRS.getIdentifier() );
548 gm.setWidth( (int) ( origWidth * ratio ) );
549 gm.setHeight( (int) ( origHeight * ratio ) );
550
551 Object o = handleFeatureInfo( request );
552 if ( o instanceof BufferedImage ) {
553 return transformBack.transform( (BufferedImage) o, dataBBOX, requestBBOX, origWidth,
554 origHeight, 16, 3, null );
555 }
556
557 return o;
558 }
559 }
560 } catch ( UnknownCRSException e ) {
561 LOG.logError( e.getLocalizedMessage(), e );
562 } catch ( CRSTransformationException e ) {
563 LOG.logError( "An error occurred while transforming bounding boxes (this should not happen)", e );
564 }
565
566 String us = constructRequestURL( request.getRequestParameter(), validateHTTPGetBaseURL( url.toExternalForm() ) );
567
568 String result = null;
569 try {
570 LOG.logDebug( "GetFeatureInfo: ", us );
571 URL ur = new URL( us );
572 // get map from the remote service
573 NetWorker nw = new NetWorker( ur );
574 byte[] b = nw.getDataAsByteArr( 20000 );
575 String contentType = nw.getContentType();
576
577 // extract content charset if available; otherwise use configured system charset
578 String charset = null;
579 LOG.logDebug( "content type: ", contentType );
580 if ( contentType != null ) {
581 String[] tmp = StringTools.toArray( contentType, ";", false );
582 if ( tmp.length == 2 ) {
583 charset = tmp[1].substring( tmp[1].indexOf( '=' ) + 1, tmp[1].length() );
584 } else {
585 charset = CharsetUtils.getSystemCharset();
586 }
587 } else {
588 charset = CharsetUtils.getSystemCharset();
589 }
590
591 // commented out checks, we're trying to fix broken GFI responses here, after all
592 // if ( contentType != null && contentType.toLowerCase().startsWith( "application/vnd.ogc.gml" ) ) {
593 result = new String( b, charset );
594 // } else {
595 // throw new OGCWebServiceException( "RemoteWMS:handleFeatureInfo" );
596 // }
597 } catch ( Exception e ) {
598 LOG.logError( e.getMessage(), e );
599 String msg = Messages.getMessage( "REMOTEWMS_GFI_GENERAL_ERROR",
600 capabilities.getServiceIdentification().getTitle(), us );
601 throw new OGCWebServiceException( "RemoteWMS:handleFeatureInfo", msg );
602 }
603
604 return result;
605 }
606
607 /**
608 * reads the capabilities from the remote WMS by performing a GetCapabilities request against it.
609 *
610 * @param request
611 * capabilities request
612 * @return remote capabilities
613 * @throws OGCWebServiceException
614 * if the request could not be executed correctly.
615 */
616 protected WMSCapabilities handleGetCapabilities( WMSGetCapabilities request )
617 throws OGCWebServiceException {
618
619 URL url = null;
620
621 if ( request.getVersion().equals( "1.0.0" ) ) {
622 url = addresses.get( CAPABILITIES_NAME );
623 } else {
624 url = addresses.get( GETCAPABILITIES_NAME );
625 }
626
627 String us = constructRequestURL( request.getRequestParameter(), validateHTTPGetBaseURL( url.toExternalForm() ) );
628
629 WMSCapabilities result = null;
630
631 try {
632 URL ur = new URL( us );
633 // get map from the remote service
634 NetWorker nw = new NetWorker( ur );
635 byte[] b = nw.getDataAsByteArr( 20000 );
636 String contentType = nw.getContentType();
637
638 if ( MimeTypeMapper.isKnownMimeType( contentType ) ) {
639 // create a WMSCapabilitiesTEMP instance from the result
640 StringReader reader = new StringReader( new String( b ) );
641 WMSCapabilitiesDocument doc = new WMSCapabilitiesDocument();
642 doc.load( reader, XMLFragment.DEFAULT_URL );
643 doc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument( doc.getRootElement() );
644 result = (WMSCapabilities) doc.parseCapabilities();
645 } else {
646 String msg = Messages.getMessage( "REMOTEWMS_GETCAPS_INVALID_CONTENTTYPE", contentType, us );
647 throw new OGCWebServiceException( "RemoteWMS:handleGetCapabilities", msg );
648 }
649 } catch ( Exception e ) {
650 LOG.logError( e.getMessage(), e );
651 String msg = Messages.getMessage( "REMOTEWMS_GETCAPS_GENERAL_ERROR",
652 capabilities.getServiceIdentification().getTitle(), us );
653 throw new OGCWebServiceException( "RemoteWMS:handleGetCapabilities", msg );
654 }
655
656 return result;
657 }
658
659 /**
660 *
661 *
662 * @param request
663 * get styles request (WMS 1.1.1 - SLD)
664 * @return <code>null</code>
665 * @throws OGCWebServiceException
666 * if the url in the request is <code>null</code>
667 */
668 protected Object handleGetStyles( GetStyles request )
669 throws OGCWebServiceException {
670
671 URL url = addresses.get( GETSTYLES_NAME );
672
673 if ( url == null ) {
674 throw new OGCWebServiceException( "GetStyles is not supported by the RemoteWMS: "
675 + capabilities.getServiceIdentification().getTitle() );
676 }
677
678 constructRequestURL( request.getRequestParameter(), validateHTTPGetBaseURL( url.toExternalForm() ) );
679
680 // FIXME
681 // TODO
682 return null;
683 }
684
685 /**
686 *
687 *
688 * @param request
689 * put styles request (WMS 1.1.1 - SLD)
690 * @return <code>null</code>
691 * @throws OGCWebServiceException
692 * if the url in the request is <code>null</code>
693 */
694 protected Object handlePutStyles( PutStyles request )
695 throws OGCWebServiceException {
696
697 URL url = addresses.get( PUTSTYLES_NAME );
698
699 if ( url == null ) {
700 throw new OGCWebServiceException( "PUTSTYLES is not supported by the RemoteWMS: "
701 + capabilities.getServiceIdentification().getTitle() );
702 }
703
704 constructRequestURL( request.getRequestParameter(), validateHTTPGetBaseURL( url.toExternalForm() ) );
705
706 // FIXME
707 // TODO
708
709 return null;
710 }
711
712 /**
713 *
714 *
715 * @param request
716 * describe layer request (WMS 1.1.1 - SLD)
717 * @return <code>null</code>
718 * @throws OGCWebServiceException
719 * if the url in the request is <code>null</code>
720 */
721 protected Object handleDescribeLayer( DescribeLayer request )
722 throws OGCWebServiceException {
723
724 URL url = addresses.get( DESCRIBELAYER_NAME );
725
726 if ( url == null ) {
727 throw new OGCWebServiceException( "DESCRIBELAYER is not supported by the RemoteWMS: "
728 + capabilities.getServiceIdentification().getTitle() );
729 }
730
731 constructRequestURL( request.getRequestParameter(), validateHTTPGetBaseURL( url.toExternalForm() ) );
732
733 // FIXME
734 // TODO
735
736 return null;
737 }
738
739 /**
740 *
741 *
742 * @param request
743 * describe layer request (WMS 1.1.1 - SLD)
744 * @return <code>null</code>
745 * @throws OGCWebServiceException
746 * if the url in the request is <code>null</code>
747 */
748 protected Object handleGetLegendGraphic( GetLegendGraphic request )
749 throws OGCWebServiceException {
750
751 URL url = addresses.get( GETLEGENDGRAPHIC_NAME );
752
753 if ( url == null ) {
754 throw new OGCWebServiceException( "GETLEGENDGRAPHIC is not supported by the RemoteWMS: "
755 + capabilities.getServiceIdentification().getTitle() );
756 }
757
758 String address = constructRequestURL( request.getRequestParameter(),
759 validateHTTPGetBaseURL( url.toExternalForm() ) );
760
761 try {
762 URL theURL = new URL( address );
763 LOG.logDebug( "Getting legend from remote WMS, URL: ", theURL );
764 BufferedImage img = ImageIO.read( theURL );
765 if ( img == null ) {
766 XMLFragment doc = new XMLFragment( theURL );
767 LOG.logDebug( "Got error message: ", doc.getAsPrettyString() );
768 return new IOException( "Service exception recieved" );
769 }
770 return img;
771 } catch ( MalformedURLException e ) {
772 return e;
773 } catch ( IOException e ) {
774 return e;
775 } catch ( SAXException e ) {
776 return e;
777 }
778 }
779
780 /**
781 *
782 *
783 * @param is
784 *
785 * @return thr content as String
786 *
787 * @throws IOException
788 */
789 protected String getInputStreamContent( InputStream is )
790 throws IOException {
791 StringBuffer sb = new StringBuffer( 1000 );
792 int c = 0;
793
794 while ( ( c = is.read() ) >= 0 ) {
795 sb.append( (char) c );
796 }
797
798 is.close();
799 return sb.toString();
800 }
801
802 }