001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/wms/configuration/WMSConfigurationDocument_1_3_0.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 This file is part of deegree. 004 Copyright (C) 2001-2007 by: 005 Department of Geography, University of Bonn 006 http://www.giub.uni-bonn.de/deegree/ 007 lat/lon GmbH 008 http://www.lat-lon.de 009 This library is free software; you can redistribute it and/or 010 modify it under the terms of the GNU Lesser General Public 011 License as published by the Free Software Foundation; either 012 version 2.1 of the License, or (at your option) any later version. 013 This library is distributed in the hope that it will be useful, 014 but WITHOUT ANY WARRANTY; without even the implied warranty of 015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 016 Lesser General Public License for more details. 017 You should have received a copy of the GNU Lesser General Public 018 License along with this library; if not, write to the Free Software 019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 Contact: 021 Andreas Poth 022 lat/lon GmbH 023 Aennchenstrasse 19 024 53177 Bonn 025 Germany 026 E-Mail: poth@lat-lon.de 027 Jens Fitzke 028 lat/lon GmbH 029 Aennchenstrasse 19 030 53177 Bonn 031 Germany 032 E-Mail: jens.fitzke@uni-bonn.de 033 ---------------------------------------------------------------------------*/ 034 package org.deegree.ogcwebservices.wms.configuration; 035 036 import java.awt.Color; 037 import java.io.IOException; 038 import java.net.MalformedURLException; 039 import java.net.URL; 040 import java.util.ArrayList; 041 import java.util.Arrays; 042 import java.util.HashMap; 043 import java.util.List; 044 import java.util.Map; 045 046 import javax.xml.transform.TransformerException; 047 048 import org.deegree.datatypes.QualifiedName; 049 import org.deegree.enterprise.Proxy; 050 import org.deegree.framework.log.ILogger; 051 import org.deegree.framework.log.LoggerFactory; 052 import org.deegree.framework.util.BootLogger; 053 import org.deegree.framework.util.IDGenerator; 054 import org.deegree.framework.util.KVP2Map; 055 import org.deegree.framework.util.StringTools; 056 import org.deegree.framework.xml.InvalidConfigurationException; 057 import org.deegree.framework.xml.XMLFragment; 058 import org.deegree.framework.xml.XMLParsingException; 059 import org.deegree.framework.xml.XMLTools; 060 import org.deegree.framework.xml.XSLTDocument; 061 import org.deegree.model.crs.UnknownCRSException; 062 import org.deegree.model.metadata.iso19115.OnlineResource; 063 import org.deegree.model.spatialschema.Envelope; 064 import org.deegree.model.spatialschema.GMLGeometryAdapter; 065 import org.deegree.model.spatialschema.Geometry; 066 import org.deegree.model.spatialschema.GeometryException; 067 import org.deegree.ogcbase.CommonNamespaces; 068 import org.deegree.ogcwebservices.OGCWebService; 069 import org.deegree.ogcwebservices.getcapabilities.MetadataURL; 070 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities; 071 import org.deegree.ogcwebservices.wcs.WCService; 072 import org.deegree.ogcwebservices.wcs.configuration.WCSConfiguration; 073 import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage; 074 import org.deegree.ogcwebservices.wfs.RemoteWFService; 075 import org.deegree.ogcwebservices.wfs.WFServiceFactory; 076 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities; 077 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument; 078 import org.deegree.ogcwebservices.wfs.configuration.WFSConfiguration; 079 import org.deegree.ogcwebservices.wfs.configuration.WFSConfigurationDocument; 080 import org.deegree.ogcwebservices.wfs.operation.Query; 081 import org.deegree.ogcwebservices.wms.RemoteWMService; 082 import org.deegree.ogcwebservices.wms.capabilities.Attribution; 083 import org.deegree.ogcwebservices.wms.capabilities.AuthorityURL; 084 import org.deegree.ogcwebservices.wms.capabilities.DataURL; 085 import org.deegree.ogcwebservices.wms.capabilities.Dimension; 086 import org.deegree.ogcwebservices.wms.capabilities.FeatureListURL; 087 import org.deegree.ogcwebservices.wms.capabilities.Identifier; 088 import org.deegree.ogcwebservices.wms.capabilities.Layer; 089 import org.deegree.ogcwebservices.wms.capabilities.LayerBoundingBox; 090 import org.deegree.ogcwebservices.wms.capabilities.LegendURL; 091 import org.deegree.ogcwebservices.wms.capabilities.ScaleHint; 092 import org.deegree.ogcwebservices.wms.capabilities.Style; 093 import org.deegree.ogcwebservices.wms.capabilities.StyleSheetURL; 094 import org.deegree.ogcwebservices.wms.capabilities.StyleURL; 095 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities; 096 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument; 097 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument_1_3_0; 098 import org.deegree.ogcwebservices.wms.operation.GetMap; 099 import org.deegree.owscommon_new.OperationsMetadata; 100 import org.deegree.owscommon_new.ServiceIdentification; 101 import org.deegree.owscommon_new.ServiceProvider; 102 import org.w3c.dom.Element; 103 import org.w3c.dom.Node; 104 import org.xml.sax.SAXException; 105 106 /** 107 * <code>WMSConfigurationDocument_1_3_0</code> is the parser class for a WMS 1.3.0 configuration 108 * document. 109 * 110 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a> 111 * @author last edited by: $Author: aschmitz $ 112 * 113 * @version 2.0, $Revision: 8112 $, $Date: 2007-09-05 14:57:09 +0200 (Mi, 05 Sep 2007) $ 114 * 115 * @since 2.0 116 */ 117 118 public class WMSConfigurationDocument_1_3_0 extends WMSCapabilitiesDocument_1_3_0 { 119 120 private static final long serialVersionUID = -2304421871404603016L; 121 122 private static Map<URL, OGCCapabilities> capaCache = new HashMap<URL, OGCCapabilities>(); 123 124 private static final String XML_TEMPLATE = "WMSConfigurationTemplate_1_3_0.xml"; 125 126 private static final String XSLT_TEMPLATE_NAME = "WMSConfigurationTransform_1_3_0.xsl"; 127 128 private static XSLTDocument XSLT_TEMPLATE; 129 130 private static final ILogger LOG = LoggerFactory.getLogger( WMSConfigurationDocument_1_3_0.class ); 131 132 private static final String PWMS = CommonNamespaces.WMS_PREFIX + ":"; 133 134 private static final QualifiedName DEFAULT_GEO_PROP = new QualifiedName( 135 "app", 136 "GEOM", 137 CommonNamespaces.buildNSURI( "http://www.deegree.org/app" ) ); 138 static { 139 XSLT_TEMPLATE = new XSLTDocument(); 140 try { 141 XSLT_TEMPLATE.load( WMSConfigurationDocument_1_3_0.class.getResource( XSLT_TEMPLATE_NAME ) ); 142 } catch ( Exception e ) { 143 BootLogger.logError( "Error loading XSLT sheet in WMSConfigurationDocument_1_3_0.", e ); 144 } 145 } 146 147 @Override 148 public void createEmptyDocument() 149 throws IOException, SAXException { 150 URL url = WMSConfigurationDocument_1_3_0.class.getResource( XML_TEMPLATE ); 151 if ( url == null ) { 152 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." ); 153 } 154 load( url ); 155 } 156 157 /** 158 * Added the prefix. 159 * 160 * @return the parsed configuration 161 * @throws InvalidConfigurationException 162 * @throws XMLParsingException 163 */ 164 public WMSConfiguration_1_3_0 parseConfiguration() 165 throws InvalidConfigurationException, XMLParsingException { 166 167 try { 168 // transform document to fill missing elements and attributes with 169 // default values 170 XMLFragment frag = XSLT_TEMPLATE.transform( this ); 171 this.setRootElement( frag.getRootElement() ); 172 } catch ( TransformerException e ) { 173 String msg = "Error transforming WMS configuration document (in order to fill in default value)."; 174 LOG.logError( msg, e ); 175 throw new InvalidConfigurationException( msg, e ); 176 } 177 178 ServiceIdentification serviceIdentification = null; 179 ServiceProvider serviceProvider = null; 180 OperationsMetadata metadata = null; 181 Layer layer = null; 182 WMSDeegreeParams params = null; 183 Element root = getRootElement(); 184 String version = XMLTools.getRequiredNodeAsString( root, "@version", nsContext ); 185 String updateSeq = XMLTools.getNodeAsString( root, "@updateSequence", nsContext, null ); 186 187 int layerLimit = 0; 188 189 try { 190 Node node = XMLTools.getRequiredNode( root, "./deegreewms:DeegreeParam", nsContext ); 191 params = parseDeegreeParams( node ); 192 193 Element serviceElement = (Element) XMLTools.getRequiredNode( root, PWMS + "Service", nsContext ); 194 195 layerLimit = XMLTools.getNodeAsInt( serviceElement, PWMS + "LayerLimit", nsContext, 0 ); 196 int maxWidth = XMLTools.getNodeAsInt( serviceElement, PWMS + "MaxWidth", nsContext, 0 ); 197 int maxHeight = XMLTools.getNodeAsInt( serviceElement, PWMS + "MaxHeight", nsContext, 0 ); 198 199 params.setMaxMapHeight( maxHeight ); 200 params.setMaxMapWidth( maxWidth ); 201 202 serviceIdentification = parseServiceIdentification(); 203 serviceProvider = parseServiceProvider(); 204 metadata = parseOperationsMetadata(); 205 206 Element layerElem = (Element) XMLTools.getRequiredNode( getRootElement(), PWMS + "Capability/" + PWMS 207 + "Layer", nsContext ); 208 layer = parseLayers( layerElem, null, null ); 209 210 } catch ( XMLParsingException e ) { 211 e.printStackTrace(); 212 throw new InvalidConfigurationException( e.getMessage() + StringTools.stackTraceToString( e ) ); 213 } catch ( MalformedURLException e ) { 214 throw new InvalidConfigurationException( e.getMessage() + " - " + StringTools.stackTraceToString( e ) ); 215 } catch ( UnknownCRSException e ) { 216 throw new InvalidConfigurationException( e.getMessage() + " - " + StringTools.stackTraceToString( e ) ); 217 } 218 219 WMSConfiguration_1_3_0 wmsConfiguration = new WMSConfiguration_1_3_0( version, updateSeq, 220 serviceIdentification, serviceProvider, 221 metadata, layer, params, getSystemId(), 222 layerLimit ); 223 224 return wmsConfiguration; 225 } 226 227 /** 228 * Creates a class representation of the <code>deegreeParams</code>- section. 229 * 230 * @param root 231 * 232 * @return the deegree params 233 * @throws XMLParsingException 234 * @throws MalformedURLException 235 */ 236 public WMSDeegreeParams parseDeegreeParams( Node root ) 237 throws XMLParsingException, MalformedURLException { 238 239 Element elem = (Element) XMLTools.getRequiredNode( root, "./deegreewms:DefaultOnlineResource", nsContext ); 240 OnlineResource ol = parseOnLineResource( elem ); 241 int cache = XMLTools.getNodeAsInt( root, "./deegreewms:CacheSize", nsContext, 100 ); 242 int maxLifeTime = XMLTools.getNodeAsInt( root, "./deegreewms:MaxLifeTime", nsContext, 3600 ); 243 int reqTimeLimit = XMLTools.getNodeAsInt( root, "./deegreewms:RequestTimeLimit", nsContext, 15 ); 244 reqTimeLimit *= 1000; 245 double mapQuality = XMLTools.getNodeAsDouble( root, "./deegreewms:MapQuality", nsContext, 0.95 ); 246 // int maxMapWidth = XMLTools.getNodeAsInt( root, "./deegreewms:MaxMapWidth", nsContext, 247 // 1000 ); 248 // int maxMapHeight = XMLTools.getNodeAsInt( root, "./deegreewms:MaxMapHeight", nsContext, 249 // 1000 ); 250 int featureInfoRadius = XMLTools.getNodeAsInt( root, "./deegreewms:FeatureInfoRadius", nsContext, 5 ); 251 String copyright = XMLTools.getNodeAsString( root, "./deegreewms:Copyright", nsContext, "" ); 252 253 URL dtdLocation = null; 254 if ( XMLTools.getNode( root, "deegreewms:DTDLocation", nsContext ) != null ) { 255 elem = (Element) XMLTools.getRequiredNode( root, "./deegreewms:DTDLocation/deegreewms:OnlineResource", 256 nsContext ); 257 OnlineResource olr = parseOnLineResource( elem ); 258 dtdLocation = olr.getLinkage().getHref(); 259 } else { 260 dtdLocation = new URL( "http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd" ); 261 } 262 263 URL featureSchemaLocation = null; 264 String featureSchemaNamespace = null; 265 if ( XMLTools.getNode( root, "deegreewms:FeatureInfoSchema", nsContext ) != null ) { 266 featureSchemaNamespace = XMLTools.getRequiredNodeAsString( 267 root, 268 "deegreewms:FeatureInfoSchema/deegreewms:Namespace", 269 nsContext ); 270 elem = (Element) XMLTools.getRequiredNode( root, "deegreewms:FeatureInfoSchema/deegreewms:OnlineResource", 271 nsContext ); 272 OnlineResource link = parseOnLineResource( elem ); 273 featureSchemaLocation = link.getLinkage().getHref(); 274 } 275 276 boolean antiAliased = XMLTools.getNodeAsBoolean( root, "./deegreewms:AntiAliased", nsContext, true ); 277 278 Proxy proxy = parseProxy( root ); 279 280 List<String> supportedVersions = parseSupportedVersions( root ); 281 282 WMSDeegreeParams deegreeParams = new WMSDeegreeParams( cache, maxLifeTime, reqTimeLimit, (float) mapQuality, 283 ol, 0, 0, antiAliased, featureInfoRadius, copyright, 284 null, dtdLocation, proxy, supportedVersions, 285 featureSchemaLocation, featureSchemaNamespace ); 286 287 return deegreeParams; 288 } 289 290 // returns the list of supported versions 291 private List<String> parseSupportedVersions( Node root ) 292 throws XMLParsingException { 293 294 String[] versions = XMLTools.getNodesAsStrings( root, "./deegreewms:SupportedVersion", nsContext ); 295 296 if ( versions != null ) 297 return Arrays.asList( versions ); 298 299 return new ArrayList<String>(); 300 301 } 302 303 /** 304 * @param root 305 * @return the proxy 306 * @throws XMLParsingException 307 */ 308 private Proxy parseProxy( Node root ) 309 throws XMLParsingException { 310 311 Proxy proxy = null; 312 Node pro = XMLTools.getNode( root, "./deegreewms:Proxy", nsContext ); 313 if ( pro != null ) { 314 String proxyHost = XMLTools.getRequiredNodeAsString( pro, "./@proxyHost", nsContext ); 315 String proxyPort = XMLTools.getRequiredNodeAsString( pro, "./@proxyPort", nsContext ); 316 proxy = new Proxy( proxyHost, proxyPort ); 317 } 318 319 return proxy; 320 } 321 322 /* 323 * Removed Extent. Added prefix. Changed SRS to CRS. 324 */ 325 @Override 326 protected Layer parseLayers( Element layerElem, Layer parent, ScaleHint scaleHint ) 327 throws XMLParsingException, UnknownCRSException { 328 329 boolean queryable = XMLTools.getNodeAsBoolean( layerElem, "./@queryable", nsContext, false ); 330 int cascaded = XMLTools.getNodeAsInt( layerElem, "./@cascaded", nsContext, 0 ); 331 boolean opaque = XMLTools.getNodeAsBoolean( layerElem, "./@opaque", nsContext, false ); 332 boolean noSubsets = XMLTools.getNodeAsBoolean( layerElem, "./@noSubsets", nsContext, false ); 333 int fixedWidth = XMLTools.getNodeAsInt( layerElem, "./@fixedWidth", nsContext, 0 ); 334 int fixedHeight = XMLTools.getNodeAsInt( layerElem, "./@fixedHeight", nsContext, 0 ); 335 String name = XMLTools.getNodeAsString( layerElem, PWMS + "Name", nsContext, null ); 336 String title = XMLTools.getRequiredNodeAsString( layerElem, PWMS + "Title", nsContext ); 337 String layerAbstract = XMLTools.getNodeAsString( layerElem, PWMS + "Abstract", nsContext, null ); 338 String[] keywords = XMLTools.getNodesAsStrings( layerElem, PWMS + "KeywordList/" + PWMS + "Keyword", nsContext ); 339 String[] srs = XMLTools.getNodesAsStrings( layerElem, PWMS + "CRS", nsContext ); 340 341 List<Element> nl = XMLTools.getElements( layerElem, PWMS + "BoundingBox", nsContext ); 342 // TODO 343 // substitue with Envelope 344 LayerBoundingBox[] bboxes = null; 345 if ( nl.size() == 0 && parent != null ) { 346 // inherit BoundingBoxes from parent layer 347 bboxes = parent.getBoundingBoxes(); 348 } else { 349 bboxes = parseLayerBoundingBoxes( nl ); 350 } 351 352 Element llBox = (Element) XMLTools.getNode( layerElem, PWMS + "EX_GeographicBoundingBox", nsContext ); 353 Envelope llBoundingBox = null; 354 if ( llBox == null && parent != null ) { 355 // inherit LatLonBoundingBox parent layer 356 llBoundingBox = parent.getLatLonBoundingBox(); 357 } else { 358 llBoundingBox = parseEX_GeographicBoundingBox( llBox ); 359 } 360 361 Dimension[] dimensions = parseDimensions( layerElem ); 362 // Extent[] extents = parseExtents( layerElem ); 363 364 Attribution attribution = parseAttribution( layerElem ); 365 366 AuthorityURL[] authorityURLs = parseAuthorityURLs( layerElem ); 367 368 MetadataURL[] metadataURLs = parseMetadataURLs( layerElem ); 369 370 DataURL[] dataURLs = parseDataURL( layerElem ); 371 372 Identifier[] identifiers = parseIdentifiers( layerElem ); 373 374 FeatureListURL[] featureListURLs = parseFeatureListURL( layerElem ); 375 376 Style[] styles = parseStyles( layerElem ); 377 378 scaleHint = parseScaleHint( layerElem, scaleHint ); 379 380 AbstractDataSource[] ds = parseDataSources( layerElem, name, scaleHint ); 381 382 Layer layer = new Layer( queryable, cascaded, opaque, noSubsets, fixedWidth, fixedHeight, name, title, 383 layerAbstract, llBoundingBox, attribution, scaleHint, keywords, srs, bboxes, 384 dimensions, null, authorityURLs, identifiers, metadataURLs, dataURLs, featureListURLs, 385 styles, null, ds, parent ); 386 387 // get Child layers 388 nl = XMLTools.getElements( layerElem, PWMS + "Layer", nsContext ); 389 Layer[] layers = new Layer[nl.size()]; 390 for ( int i = 0; i < layers.length; i++ ) { 391 layers[i] = parseLayers( nl.get( i ), layer, scaleHint ); 392 } 393 394 // set child layers 395 layer.setLayer( layers ); 396 397 return layer; 398 } 399 400 /* 401 * Added the prefix. 402 */ 403 @Override 404 protected Style[] parseStyles( Element layerElem ) 405 throws XMLParsingException { 406 407 List<Element> nl = XMLTools.getElements( layerElem, PWMS + "Style", nsContext ); 408 Style[] styles = new Style[nl.size()]; 409 for ( int i = 0; i < styles.length; i++ ) { 410 String name = XMLTools.getRequiredNodeAsString( nl.get( i ), PWMS + "Name", nsContext ); 411 String title = XMLTools.getNodeAsString( nl.get( i ), PWMS + "Title", nsContext, null ); 412 String styleAbstract = XMLTools.getNodeAsString( nl.get( i ), PWMS + "Abstract", nsContext, null ); 413 LegendURL[] legendURLs = parseLegendURL( nl.get( i ) ); 414 StyleURL styleURL = parseStyleURL( nl.get( i ) ); 415 StyleSheetURL styleSheetURL = parseStyleSheetURL( nl.get( i ) ); 416 String styleResource = XMLTools.getNodeAsString( nl.get( i ), "deegreewms:StyleResource", nsContext, 417 "styles.xml" ); 418 URL sr = null; 419 try { 420 sr = resolve( styleResource ); 421 } catch ( MalformedURLException e ) { 422 throw new XMLParsingException( "could not parse style resource of style: " + name, e ); 423 } 424 styles[i] = new Style( name, title, styleAbstract, legendURLs, styleSheetURL, styleURL, sr ); 425 } 426 427 return styles; 428 } 429 430 /** 431 * 432 * @param layerElem 433 * @return the data sources 434 * @throws XMLParsingException 435 */ 436 protected AbstractDataSource[] parseDataSources( Element layerElem, String layerName, ScaleHint scaleHint ) 437 throws XMLParsingException { 438 439 List<Element> nl = XMLTools.getElements( layerElem, "./deegreewms:DataSource", nsContext ); 440 441 AbstractDataSource[] ds = new AbstractDataSource[nl.size()]; 442 for ( int i = 0; i < ds.length; i++ ) { 443 boolean failOnEx = XMLTools.getNodeAsBoolean( nl.get( i ), "./@failOnException", nsContext, true ); 444 boolean queryable = XMLTools.getNodeAsBoolean( nl.get( i ), "./@queryable", nsContext, false ); 445 QualifiedName name = XMLTools.getNodeAsQualifiedName( nl.get( i ), "./deegreewms:Name/text()", nsContext, 446 new QualifiedName( layerName ) ); 447 String stype = XMLTools.getRequiredNodeAsString( nl.get( i ), "./deegreewms:Type", nsContext ); 448 449 int reqTimeLimit = XMLTools.getNodeAsInt( nl.get( i ), "./deegreewms:RequestTimeLimit/text()", nsContext, 450 30 ); 451 452 scaleHint = parseDSScaleHint( nl.get( i ), scaleHint ); 453 454 String s = "./deegreewms:OWSCapabilities/deegreewms:OnlineResource"; 455 Element node = XMLTools.getRequiredElement( nl.get( i ), s, nsContext ); 456 457 URL url = parseOnLineResource( node ).getLinkage().getHref(); 458 459 Geometry validArea = parseValidArea( nl.get( i ) ); 460 461 try { 462 if ( "LOCALWFS".equals( stype ) ) { 463 ds[i] = createLocalWFSDataSource( nl.get( i ), failOnEx, queryable, name, url, scaleHint, 464 validArea, reqTimeLimit ); 465 } else if ( "LOCALWCS".equals( stype ) ) { 466 ds[i] = createLocalWCSDataSource( nl.get( i ), failOnEx, queryable, name, url, scaleHint, 467 validArea, reqTimeLimit ); 468 } else if ( "REMOTEWFS".equals( stype ) ) { 469 ds[i] = createRemoteWFSDataSource( nl.get( i ), failOnEx, queryable, name, url, scaleHint, 470 validArea, reqTimeLimit ); 471 } else if ( "REMOTEWCS".equals( stype ) ) { 472 // int type = AbstractDataSource.REMOTEWCS; 473 // GetCoverage getCoverage = 474 parseWCSFilterCondition( nl.get( i ) ); 475 // Color[] colors = 476 parseTransparentColors( nl.get( i ) ); 477 // TODO 478 throw new XMLParsingException( "REMOTEWCS is not supported yet!" ); 479 } else if ( "REMOTEWMS".equals( stype ) ) { 480 ds[i] = createRemoteWMSDataSource( nl.get( i ), failOnEx, queryable, name, url, scaleHint, 481 validArea, reqTimeLimit ); 482 } else { 483 throw new XMLParsingException( "invalid DataSource type: " + stype + " defined " 484 + "in deegree WMS configuration for DataSource: " + name ); 485 } 486 } catch ( Exception e ) { 487 e.printStackTrace(); 488 throw new XMLParsingException( "could not create service instance for WMS datasource: " + name, e ); 489 } 490 } 491 492 return ds; 493 } 494 495 /** 496 * parses the ScaleHint for a Datasource 497 * 498 * @param layerElem 499 * @param scaleHint 500 * @return the ScaleHint for the Datasource 501 * @throws XMLParsingException 502 */ 503 protected ScaleHint parseDSScaleHint( Element layerElem, ScaleHint scaleHint ) 504 throws XMLParsingException { 505 506 Node scNode = XMLTools.getNode( layerElem, "./deegreewms:ScaleHint", nsContext ); 507 if ( scNode != null ) { 508 double mn = XMLTools.getNodeAsDouble( scNode, "./@min", nsContext, 0 ); 509 double mx = XMLTools.getNodeAsDouble( scNode, "./@max", nsContext, Double.MAX_VALUE ); 510 scaleHint = new ScaleHint( mn, mx ); 511 } 512 513 if ( scaleHint == null ) { 514 // set default value to avoid NullPointerException 515 // when accessing a layers scalehint 516 scaleHint = new ScaleHint( 0, Double.MAX_VALUE ); 517 } 518 519 return scaleHint; 520 } 521 522 /** 523 * returns the area a data source is valid. If the optional element <ValidArea>is not defined in 524 * the configuration <code>null</code>. 525 * 526 * @param node 527 * @return the geom 528 * @throws Exception 529 */ 530 private Geometry parseValidArea( Node node ) 531 throws XMLParsingException { 532 533 Geometry geom = null; 534 535 List<Node> nl = XMLTools.getNodes( node, "./deegreewms:ValidArea/*", nsContext ); 536 if ( node != null ) { 537 538 try { 539 for ( int i = 0; i < nl.size(); i++ ) { 540 541 if ( nl.get( 0 ).getNamespaceURI().equals( GMLNS.toString() ) ) { 542 543 geom = GMLGeometryAdapter.wrap( (Element) nl.get( 0 ), null ); 544 break; 545 } 546 } 547 } catch ( GeometryException e ) { 548 e.printStackTrace(); 549 throw new XMLParsingException( "couldn't parse/create valid aera of a datasource", e ); 550 } 551 } 552 553 return geom; 554 } 555 556 /** 557 * @param node 558 * @param failOnEx 559 * @param queryable 560 * @param name 561 * @param geoProp 562 * @param url 563 * @param scaleHint 564 * @throws Exception 565 */ 566 private RemoteWMSDataSource createRemoteWMSDataSource( Node node, boolean failOnEx, boolean queryable, 567 QualifiedName name, URL url, ScaleHint scaleHint, 568 Geometry validArea, int reqTimeLimit ) 569 throws Exception { 570 int type = AbstractDataSource.REMOTEWMS; 571 572 String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource"; 573 Node fitNode = XMLTools.getNode( node, s, nsContext ); 574 URL fitURL = null; 575 if ( fitNode != null ) { 576 fitURL = parseOnLineResource( (Element) fitNode ).getLinkage().getHref(); 577 } 578 579 GetMap getMap = parseWMSFilterCondition( node ); 580 Color[] colors = parseTransparentColors( node ); 581 WMSCapabilities wCapa = null; 582 if ( capaCache.get( url ) != null ) { 583 wCapa = (WMSCapabilities) capaCache.get( url ); 584 } else { 585 WMSCapabilitiesDocument doc = new WMSCapabilitiesDocument(); 586 LOG.logDebug( "Fetching remote WMS capabilities from URL " + url ); 587 doc.load( url ); 588 LOG.logDebug( "Fetching remote WMS capabilities from URL " + url + " succeeded." ); 589 wCapa = (WMSCapabilities) doc.parseCapabilities(); 590 capaCache.put( url, wCapa ); 591 } 592 OGCWebService ows = new RemoteWMService( wCapa ); 593 594 // parse added/passed parameter map/list 595 Node vendor = XMLTools.getNode( node, 596 "deegreewms:FilterCondition/deegreewms:VendorspecificParameterDefinition", 597 nsContext ); 598 599 List<String> passedParameters = WMSConfigurationDocument.parsePassedParameters( vendor ); 600 Map<String, String> addedParameters = WMSConfigurationDocument.parseAddedParameters( vendor ); 601 602 return new RemoteWMSDataSource( queryable, failOnEx, name, type, ows, url, scaleHint, validArea, getMap, 603 colors, fitURL, reqTimeLimit, passedParameters, addedParameters ); 604 } 605 606 /** 607 * @param node 608 * @param failOnEx 609 * @param queryable 610 * @param name 611 * @param geoProp 612 * @param url 613 * @param scaleHint 614 * @throws Exception 615 */ 616 private RemoteWFSDataSource createRemoteWFSDataSource( Node node, boolean failOnEx, boolean queryable, 617 QualifiedName name, URL url, ScaleHint scaleHint, 618 Geometry validArea, int reqTimeLimit ) 619 throws Exception { 620 int type = AbstractDataSource.REMOTEWFS; 621 String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource"; 622 Node fitNode = XMLTools.getNode( node, s, nsContext ); 623 URL fitURL = null; 624 if ( fitNode != null ) { 625 fitURL = parseOnLineResource( (Element) fitNode ).getLinkage().getHref(); 626 } 627 Query query = parseWFSFilterCondition( node ); 628 629 WFSCapabilities wfsCapa = null; 630 if ( capaCache.get( url ) != null ) { 631 wfsCapa = (WFSCapabilities) capaCache.get( url ); 632 } else { 633 WFSCapabilitiesDocument wfsDoc = new WFSCapabilitiesDocument(); 634 wfsDoc.load( url ); 635 wfsCapa = (WFSCapabilities) wfsDoc.parseCapabilities(); 636 capaCache.put( url, wfsCapa ); 637 } 638 OGCWebService ows = new RemoteWFService( wfsCapa ); 639 // OGCWebService ows = null; 640 641 Node geoPropNode = XMLTools.getNode( node, "deegreewms:GeometryProperty/text()", nsContext ); 642 QualifiedName geoProp = DEFAULT_GEO_PROP; 643 if ( geoPropNode != null ) { 644 geoProp = parseQualifiedName( geoPropNode ); 645 } 646 647 return new RemoteWFSDataSource( queryable, failOnEx, name, type, geoProp, ows, url, scaleHint, validArea, 648 query, fitURL, reqTimeLimit ); 649 650 } 651 652 /** 653 * @param node 654 * @param failOnEx 655 * @param queryable 656 * @param name 657 * @param geoProp 658 * @param url 659 * @param scaleHint 660 * @throws Exception 661 */ 662 private LocalWCSDataSource createLocalWCSDataSource( Node node, boolean failOnEx, boolean queryable, 663 QualifiedName name, URL url, ScaleHint scaleHint, 664 Geometry validArea, int reqTimeLimit ) 665 throws Exception { 666 int type = AbstractDataSource.LOCALWCS; 667 GetCoverage getCoverage = parseWCSFilterCondition( node ); 668 Color[] colors = parseTransparentColors( node ); 669 WCSConfiguration configuration = null; 670 if ( capaCache.get( url ) != null ) { 671 configuration = (WCSConfiguration) capaCache.get( url ); 672 } else { 673 configuration = WCSConfiguration.create( url ); 674 capaCache.put( url, configuration ); 675 } 676 677 OGCWebService ows = new WCService( configuration ); 678 679 return new LocalWCSDataSource( queryable, failOnEx, name, type, ows, url, scaleHint, validArea, getCoverage, 680 colors, reqTimeLimit ); 681 } 682 683 /** 684 * @param node 685 * @param failOnEx 686 * @param queryable 687 * @param name 688 * @param geoProp 689 * @param url 690 * @param scaleHint 691 * @throws Exception 692 */ 693 private LocalWFSDataSource createLocalWFSDataSource( Node node, boolean failOnEx, boolean queryable, 694 QualifiedName name, URL url, ScaleHint scaleHint, 695 Geometry validArea, int reqTimeLimit ) 696 throws Exception { 697 int type = AbstractDataSource.LOCALWFS; 698 String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource"; 699 Node fitNode = XMLTools.getNode( node, s, nsContext ); 700 URL fitURL = null; 701 if ( fitNode != null ) { 702 fitURL = parseOnLineResource( (Element) fitNode ).getLinkage().getHref(); 703 } 704 Query query = parseWFSFilterCondition( node ); 705 WFSConfiguration wfsCapa = null; 706 if ( capaCache.get( url ) != null ) { 707 wfsCapa = (WFSConfiguration) capaCache.get( url ); 708 } else { 709 WFSConfigurationDocument wfsDoc = new WFSConfigurationDocument(); 710 wfsDoc.load( url ); 711 wfsCapa = wfsDoc.getConfiguration(); 712 // wfsCapa = new WFSCapabilitiesDocument( url ).createCapabilities(); 713 capaCache.put( url, wfsCapa ); 714 } 715 // OGCWebService ows = WFServiceFactory.getUncachedService( wfsCapa ); 716 OGCWebService ows = WFServiceFactory.createInstance( wfsCapa ); 717 718 Node geoPropNode = XMLTools.getNode( node, "deegreewms:GeometryProperty/text()", nsContext ); 719 QualifiedName geoProp = DEFAULT_GEO_PROP; 720 if ( geoPropNode != null ) { 721 geoProp = parseQualifiedName( geoPropNode ); 722 } 723 724 LOG.logDebug( "geometry property", geoProp ); 725 726 return new LocalWFSDataSource( queryable, failOnEx, name, type, geoProp, ows, url, scaleHint, validArea, query, 727 fitURL, reqTimeLimit ); 728 } 729 730 /** 731 * @param nl 732 * @param type 733 * @throws XMLParsingException 734 */ 735 private Color[] parseTransparentColors( Node node ) 736 throws XMLParsingException { 737 738 String s = "./deegreewms:TransparentColors/deegreewms:Color"; 739 List<Node> clnl = XMLTools.getNodes( node, s, nsContext ); 740 Color[] colors = new Color[clnl.size()]; 741 for ( int j = 0; j < colors.length; j++ ) { 742 colors[j] = Color.decode( XMLTools.getStringValue( clnl.get( j ) ) ); 743 } 744 745 return colors; 746 } 747 748 /** 749 * 750 * @param node 751 * @return the query 752 * @throws XMLParsingException 753 */ 754 private Query parseWFSFilterCondition( Node node ) 755 throws XMLParsingException { 756 757 Query o = null; 758 759 Node queryNode = XMLTools.getNode( node, "./deegreewms:FilterCondition/wfs:Query", nsContext ); 760 if ( queryNode != null ) { 761 try { 762 o = Query.create( (Element) queryNode ); 763 } catch ( Exception e ) { 764 throw new XMLParsingException( StringTools.stackTraceToString( e ) ); 765 } 766 } 767 768 return o; 769 } 770 771 /** 772 * 773 * @param node 774 * @return the request object 775 * @throws XMLParsingException 776 */ 777 private GetCoverage parseWCSFilterCondition( Node node ) 778 throws XMLParsingException { 779 780 GetCoverage o = null; 781 782 String id = "" + IDGenerator.getInstance().generateUniqueID(); 783 784 StringBuffer sd = new StringBuffer( 1000 ); 785 sd.append( "version=1.0.0&Coverage=%default%&" ); 786 sd.append( "CRS=EPSG:4326&BBOX=0,0,1,1&Width=1" ); 787 sd.append( "&Height=1&Format=%default%&" ); 788 String s = XMLTools.getNodeAsString( node, "./deegreewms:FilterCondition/deegreewms:WCSRequest", nsContext, "" ); 789 sd.append( s ); 790 try { 791 o = GetCoverage.create( id, sd.toString() ); 792 } catch ( Exception e ) { 793 throw new XMLParsingException( "could not create GetCoverage from layer FilterCondition", e ); 794 } 795 796 return o; 797 } 798 799 /** 800 * 801 * @param node 802 * @return the request object 803 * @throws XMLParsingException 804 */ 805 private GetMap parseWMSFilterCondition( Node node ) 806 throws XMLParsingException { 807 808 GetMap o = null; 809 810 String id = "" + IDGenerator.getInstance().generateUniqueID(); 811 812 StringBuffer sd = new StringBuffer( 1000 ); 813 sd.append( "REQUEST=GetMap&LAYERS=%default%&" ); 814 sd.append( "STYLES=&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=1&" ); 815 sd.append( "HEIGHT=1&FORMAT=%default%" ); 816 Map<String, String> map1 = KVP2Map.toMap( sd.toString() ); 817 String s = XMLTools.getRequiredNodeAsString( node, "./deegreewms:FilterCondition/deegreewms:WMSRequest", 818 nsContext ); 819 Map<String, String> map2 = KVP2Map.toMap( s ); 820 if ( map2.get( "VERSION" ) == null && map2.get( "WMTVER" ) == null ) { 821 map2.put( "VERSION", "1.1.1" ); 822 } 823 // if no service is set use WMS as default 824 if ( map2.get( "SERVICE" ) == null ) { 825 map2.put( "SERVICE", "WMS" ); 826 } 827 map1.putAll( map2 ); 828 try { 829 map1.put( "ID", id ); 830 o = GetMap.create( map1 ); 831 } catch ( Exception e ) { 832 throw new XMLParsingException( "could not create GetMap from layer FilterCondition", e ); 833 } 834 835 return o; 836 } 837 838 }