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