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