001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/sos/configuration/SOSConfigurationDocument.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.sos.configuration; 037 038 import java.io.IOException; 039 import java.net.MalformedURLException; 040 import java.net.URI; 041 import java.net.URISyntaxException; 042 import java.net.URL; 043 import java.util.ArrayList; 044 import java.util.List; 045 046 import javax.naming.ConfigurationException; 047 import javax.xml.parsers.ParserConfigurationException; 048 049 import org.deegree.datatypes.QualifiedName; 050 import org.deegree.datatypes.xlink.SimpleLink; 051 import org.deegree.framework.log.ILogger; 052 import org.deegree.framework.log.LoggerFactory; 053 import org.deegree.framework.xml.InvalidConfigurationException; 054 import org.deegree.framework.xml.NamespaceContext; 055 import org.deegree.framework.xml.XMLParsingException; 056 import org.deegree.framework.xml.XMLTools; 057 import org.deegree.model.filterencoding.AbstractFilter; 058 import org.deegree.model.filterencoding.Filter; 059 import org.deegree.model.metadata.iso19115.Linkage; 060 import org.deegree.model.metadata.iso19115.OnlineResource; 061 import org.deegree.ogcbase.CommonNamespaces; 062 import org.deegree.ogcwebservices.OGCWebService; 063 import org.deegree.ogcwebservices.OGCWebServiceException; 064 import org.deegree.ogcwebservices.sos.capabilities.CapabilitiesDocument; 065 import org.deegree.ogcwebservices.wfs.RemoteWFService; 066 import org.deegree.ogcwebservices.wfs.WFServiceFactory; 067 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities; 068 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument; 069 import org.deegree.ogcwebservices.wfs.configuration.WFSConfigurationDocument; 070 import org.w3c.dom.Document; 071 import org.w3c.dom.Element; 072 import org.w3c.dom.Node; 073 import org.xml.sax.SAXException; 074 075 /** 076 * Reads the SOSConfiguration from a XML File 077 * 078 * @author <a href="mailto:mkulbe@lat-lon.de">Matthias Kulbe </a> 079 * 080 * @version 1.0 081 */ 082 083 public class SOSConfigurationDocument extends CapabilitiesDocument { 084 085 private static final String XML_TEMPLATE = "SOSConfigurationTemplate.xml"; 086 087 protected static final URI DEEGREE_SOS = CommonNamespaces.DEEGREESOS; 088 089 private static final ILogger LOG = LoggerFactory.getLogger( SOSConfigurationDocument.class ); 090 091 private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext(); 092 093 /** 094 * creates a empty document from template File 095 */ 096 public void createEmptyDocument() 097 throws IOException, SAXException { 098 URL url = SOSConfigurationDocument.class.getResource( XML_TEMPLATE ); 099 if ( url == null ) { 100 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." ); 101 } 102 this.load( url ); 103 } 104 105 /** 106 * returns a class representation of the document 107 * 108 * @return a class representation of the document 109 * @throws InvalidConfigurationException 110 */ 111 public SOSConfiguration getConfiguration() 112 throws InvalidConfigurationException { 113 114 try { 115 return new SOSConfiguration( getSOSDeegreeParams(), getSensorList(), getPlatformList(), 116 getOperationsMetadata(), getServiceProvider(), getServiceIdentification(), 117 parseUpdateSequence(), parseVersion(), null ); 118 119 } catch ( Exception e ) { 120 LOG.logError( e.getMessage(), e ); 121 throw new InvalidConfigurationException( "Class representation of the SOS configuration " 122 + "document could not be generated: " + e.getMessage() ); 123 } 124 125 } 126 127 /** 128 * reads the scs deegree params from xml file 129 * 130 * @return 131 * @throws InvalidConfigurationException 132 * @throws ParserConfigurationException 133 * @throws XMLParsingException 134 * @throws URISyntaxException 135 * @throws IOException 136 */ 137 private SOSDeegreeParams getSOSDeegreeParams() 138 throws XMLParsingException { 139 140 Document doc = this.getRootElement().getOwnerDocument(); 141 142 try { 143 if ( doc != null ) { 144 145 String defaultOnlineResourceHref = XMLTools.getRequiredNodeAsString( 146 doc, 147 "sos:SCS_Capabilities/deegreesos:" 148 + "deegreeParams/deegreesos:DefaultOnlineResource/@xlink:href", 149 nsContext ); 150 151 String defaultOnlineResourceType = XMLTools.getRequiredNodeAsString( 152 doc, 153 "sos:SCS_Capabilities/deegreesos:" 154 + "deegreeParams/deegreesos:DefaultOnlineResource/@xlink:type", 155 nsContext ); 156 int cacheSize = XMLTools.getRequiredNodeAsInt( doc, "sos:SCS_Capabilities/deegreesos:" 157 + "deegreeParams/deegreesos:CacheSize", nsContext ); 158 159 int requestTimeLimit = XMLTools.getRequiredNodeAsInt( 160 doc, 161 "sos:SCS_Capabilities/deegreesos:deegreeParams/" 162 + "deegreesos:RequestTimeLimit", 163 nsContext ); 164 165 String characterSet = XMLTools.getRequiredNodeAsString( doc, "sos:SCS_Capabilities/deegreesos:" 166 + "deegreeParams/deegreesos:Encoding", 167 nsContext ); 168 169 int sourceServerTimeLimit = XMLTools.getRequiredNodeAsInt( 170 doc, 171 "sos:SCS_Capabilities/deegreesos:" 172 + "deegreeParams/deegreesos:SourceServerTimeLimit", 173 nsContext ); 174 175 // gets the sourceServer configs 176 SourceServerConfiguration[] sourceServers = getSourceServerConfigs( doc ); 177 LOG.logDebug( "found " + sourceServers.length + " Servers" ); 178 179 // gets the platform configs 180 PlatformConfiguration[] platforms = getPlatformConfigs( doc, sourceServers ); 181 LOG.logDebug( "found " + platforms.length + " Platforms" ); 182 183 // gets the sensor configs 184 SensorConfiguration[] sensors = getSensorConfigs( doc, sourceServers ); 185 LOG.logDebug( "found " + sensors.length + " Sensors" ); 186 187 URL url = new URL( defaultOnlineResourceHref ); 188 Linkage linkage = new Linkage( url, defaultOnlineResourceType ); 189 return new SOSDeegreeParams( new OnlineResource( linkage ), cacheSize, requestTimeLimit, characterSet, 190 sourceServerTimeLimit, sensors, platforms, sourceServers ); 191 192 } 193 194 throw new IOException( "can't access to the configuration document" ); 195 196 } catch ( Exception e ) { 197 throw new XMLParsingException( "could not parse SOS configuration DeegreeParam " + "section", e ); 198 } 199 200 } 201 202 /** 203 * reads all sensor configs from xml file 204 * 205 * @return 206 * @throws XMLParsingException 207 * @throws MalformedURLException 208 * @throws XMLParsingException 209 * @throws URISyntaxException 210 * @throws ConfigurationException 211 */ 212 private SensorConfiguration[] getSensorConfigs( Document doc, SourceServerConfiguration[] sourceServers ) 213 throws MalformedURLException, XMLParsingException { 214 215 ArrayList<SensorConfiguration> sensors = new ArrayList<SensorConfiguration>(); 216 217 List parts = XMLTools.getNodes( doc, "sos:SCS_Capabilities/sos:SensorList/sos:Sensor", nsContext ); 218 219 for ( int i = 0; i < parts.size(); i++ ) { 220 221 String id = XMLTools.getRequiredNodeAsString( (Node) parts.get( i ), "@Id", nsContext ); 222 223 String idPropertyValue = XMLTools.getRequiredNodeAsString( 224 (Node) parts.get( i ), 225 "deegreesos:DescriptionSource/deegreesos:IdPropertyValue/text()", 226 nsContext ); 227 228 String sourceServerId = XMLTools.getRequiredNodeAsString( 229 (Node) parts.get( i ), 230 "deegreesos:DescriptionSource/deegreesos:SourceServerID/text()", 231 nsContext ); 232 233 List measurements = XMLTools.getNodes( (Node) parts.get( i ), 234 "deegreesos:MeasurementList/deegreesos:Measurement", nsContext ); 235 236 SensorConfiguration temp = new SensorConfiguration( id, idPropertyValue, sourceServerId, 237 getMeasurementConfigs( measurements ) ); 238 239 if ( sensors.contains( temp ) ) { 240 LOG.logWarning( "Sensor id's have to be unique! Sensor not added!" ); 241 } else { 242 for ( int a = 0; a < sourceServers.length; a++ ) { 243 if ( sourceServers[a].getId().equals( sourceServerId ) ) { 244 if ( sourceServers[a].haveSensorDescriptionData() ) { 245 LOG.logDebug( "-> found Sensor on " + sourceServers[a].getId() ); 246 sourceServers[a].addSensor( temp ); 247 sensors.add( temp ); 248 } else { 249 LOG.logWarning( "Server can't support DescribeSensor! " + "Sensor not added!" ); 250 } 251 } 252 } 253 } 254 } 255 256 return sensors.toArray( new SensorConfiguration[sensors.size()] ); 257 } 258 259 /** 260 * reads the measurements from a sensor 261 * 262 * @param node 263 * 264 * @return 265 * @throws XMLParsingException 266 * @throws MalformedURLException 267 * @throws URISyntaxException 268 */ 269 private MeasurementConfiguration[] getMeasurementConfigs( List parts ) 270 throws XMLParsingException, MalformedURLException { 271 272 ArrayList<MeasurementConfiguration> measurements = new ArrayList<MeasurementConfiguration>(); 273 274 if ( ( parts == null ) || ( parts.size() < 1 ) ) { 275 LOG.logWarning( "Sensor must have at least one Measures" ); 276 } 277 278 for ( int i = 0; i < parts.size(); i++ ) { 279 280 String id = XMLTools.getRequiredNodeAsString( (Node) parts.get( i ), "@id", nsContext ); 281 282 String sourceServerId = XMLTools.getRequiredNodeAsString( (Node) parts.get( i ), 283 "deegreesos:SourceServerID/text()", nsContext ); 284 285 String phenomenon = XMLTools.getRequiredNodeAsString( (Node) parts.get( i ), "@phenomenon", nsContext ); 286 287 QualifiedName featureTypeName = XMLTools.getRequiredNodeAsQualifiedName( 288 (Node) parts.get( i ), 289 "deegreesos:FeatureTypeName/text()", 290 nsContext ); 291 292 Node constraint = XMLTools.getNode( (Node) parts.get( i ), "deegreesos:Constraint/ogc:Filter", nsContext ); 293 Filter filter = null; 294 if ( constraint != null ) { 295 filter = AbstractFilter.buildFromDOM( (Element) constraint ); 296 } 297 298 QualifiedName timePropertyName = XMLTools.getRequiredNodeAsQualifiedName( 299 (Node) parts.get( i ), 300 "deegreesos:TimePropertyName/text()", 301 nsContext ); 302 303 QualifiedName measurandPropertyName = XMLTools.getRequiredNodeAsQualifiedName( 304 (Node) parts.get( i ), 305 "deegreesos:MeasurandPropertyName/text()", 306 nsContext ); 307 308 String timeResolution = XMLTools.getNodeAsString( (Node) parts.get( i ), 309 "deegreesos:TimeResolution/text()", nsContext, null ); 310 311 String timeResolutionType = null; 312 313 if ( timeResolution != null ) { 314 timeResolutionType = XMLTools.getRequiredNodeAsString( (Node) parts.get( i ), 315 "deegreesos:TimeResolution/@type", nsContext ); 316 } 317 318 URL xsltSource = resolve( XMLTools.getRequiredNodeAsString( (Node) parts.get( i ), 319 "deegreesos:XSLTSource/text()", nsContext ) ); 320 321 MeasurementConfiguration temp = new MeasurementConfiguration( id, sourceServerId, phenomenon, 322 featureTypeName, filter, timePropertyName, 323 measurandPropertyName, timeResolution, 324 timeResolutionType, xsltSource ); 325 326 if ( measurements.contains( temp ) ) { 327 LOG.logWarning( "measurement id's have to be unique! Measurement not added!" ); 328 } else { 329 measurements.add( temp ); 330 } 331 332 } 333 334 MeasurementConfiguration[] tmp = new MeasurementConfiguration[measurements.size()]; 335 return measurements.toArray( tmp ); 336 } 337 338 /** 339 * reads all platform configs from xml file 340 * 341 * @param doc 342 * 343 * @throws MalformedURLException 344 * @throws XMLParsingException 345 */ 346 private PlatformConfiguration[] getPlatformConfigs( Document doc, SourceServerConfiguration[] sourceServers ) 347 throws XMLParsingException { 348 349 ArrayList<PlatformConfiguration> platforms = new ArrayList<PlatformConfiguration>(); 350 351 List parts = XMLTools.getNodes( doc, "sos:SCS_Capabilities/sos:PlatformList/sos:Platform", nsContext ); 352 353 for ( int i = 0; i < parts.size(); i++ ) { 354 355 String id = XMLTools.getRequiredNodeAsString( (Node) parts.get( i ), "@Id", nsContext ); 356 357 String idPropertyValue = XMLTools.getRequiredNodeAsString( 358 (Node) parts.get( i ), 359 "deegreesos:DescriptionSource/deegreesos:IdPropertyValue/text()", 360 nsContext ); 361 362 String sourceServerId = XMLTools.getRequiredNodeAsString( 363 (Node) parts.get( i ), 364 "deegreesos:DescriptionSource/deegreesos:SourceServerID/text()", 365 nsContext ); 366 367 PlatformConfiguration temp = new PlatformConfiguration( id, idPropertyValue, sourceServerId ); 368 369 if ( platforms.contains( temp ) ) { 370 LOG.logWarning( "Platfom id's have to be unique! Platform not added!" ); 371 } else { 372 for ( int a = 0; a < sourceServers.length; a++ ) { 373 SourceServerConfiguration sso = sourceServers[a]; 374 if ( sso.getId().equals( sourceServerId ) ) { 375 if ( sso.havePlatformDescriptionData() ) { 376 LOG.logDebug( "-> found Platform on " + sso.getId() ); 377 sso.addPlatform( temp ); 378 platforms.add( temp ); 379 } else { 380 LOG.logWarning( "Server can't support DescribePlatform! " + "Platform not added!" ); 381 } 382 } 383 } 384 } 385 } 386 PlatformConfiguration[] tmp = new PlatformConfiguration[platforms.size()]; 387 return platforms.toArray( tmp ); 388 389 } 390 391 /** 392 * reads all source server configs from xml file 393 * 394 * @param node 395 * 396 * @throws XMLParsingException 397 * @throws MalformedURLException 398 * @throws URISyntaxException 399 */ 400 private SourceServerConfiguration[] getSourceServerConfigs( Node node ) 401 throws XMLParsingException, MalformedURLException, OGCWebServiceException, IOException, 402 SAXException, InvalidConfigurationException { 403 404 ArrayList<SourceServerConfiguration> sourceServers = new ArrayList<SourceServerConfiguration>(); 405 406 List sourceServerList = XMLTools.getNodes( 407 node, 408 "sos:SCS_Capabilities/" 409 + "deegreesos:deegreeParams/deegreesos:SourceServerList/deegreesos:SourceServer", 410 nsContext ); 411 412 for ( int i = 0; i < sourceServerList.size(); i++ ) { 413 414 String id = XMLTools.getRequiredNodeAsString( (Node) sourceServerList.get( i ), "@id", nsContext ); 415 416 String service = XMLTools.getRequiredNodeAsString( (Node) sourceServerList.get( i ), "@service", nsContext ); 417 418 String version = XMLTools.getRequiredNodeAsString( (Node) sourceServerList.get( i ), "@version", nsContext ); 419 420 Node olNode = XMLTools.getRequiredNode( (Node) sourceServerList.get( i ), "ogc:OnlineResource", nsContext ); 421 OGCWebService ows = getDataServiceCapaOnlineResource( olNode ); 422 423 // gets the optional platformDescription config 424 List platformDescription = XMLTools.getNodes( (Node) sourceServerList.get( i ), 425 "deegreesos:PlatformDescription", nsContext ); 426 427 if ( platformDescription.size() < 1 ) { 428 throw new XMLParsingException( "no platformDescription Config added " + "for server '" + id + "'" ); 429 } 430 431 QualifiedName platformDescriptionFeatureType = XMLTools.getRequiredNodeAsQualifiedName( 432 (Node) platformDescription.get( 0 ), 433 "deegreesos:FeatureType/text()", 434 nsContext ); 435 QualifiedName platformDescriptionIdPropertyName = XMLTools.getRequiredNodeAsQualifiedName( 436 (Node) platformDescription.get( 0 ), 437 "deegreesos:IdPropertyName/text()", 438 nsContext ); 439 QualifiedName platformDescriptionCoordPropertyName = XMLTools.getRequiredNodeAsQualifiedName( 440 (Node) platformDescription.get( 0 ), 441 "deegreesos:CoordPropertyName/text()", 442 nsContext ); 443 String platformDescriptionXSLTSource = XMLTools.getRequiredNodeAsString( 444 (Node) platformDescription.get( 0 ), 445 "deegreesos:XSLTSource/text()", 446 nsContext ); 447 448 // gets the optional SensorDescription config 449 List sensorDescription = XMLTools.getNodes( (Node) sourceServerList.get( i ), 450 "deegreesos:SensorDescription", nsContext ); 451 452 if ( sensorDescription.size() < 1 ) { 453 throw new XMLParsingException( "info: no sensorDescription Config added for " + "server '" + id + "'" ); 454 } 455 456 QualifiedName sensorDescriptionFeatureType = XMLTools.getRequiredNodeAsQualifiedName( 457 (Node) sensorDescription.get( 0 ), 458 "deegreesos:FeatureType/text()", 459 nsContext ); 460 461 QualifiedName sensorDescriptionIdPropertyName = XMLTools.getRequiredNodeAsQualifiedName( 462 (Node) sensorDescription.get( 0 ), 463 "deegreesos:IdPropertyName/text()", 464 nsContext ); 465 String sensorDescriptionXSLTSource = XMLTools.getRequiredNodeAsString( (Node) sensorDescription.get( 0 ), 466 "deegreesos:XSLTSource/text()", 467 nsContext ); 468 469 URL platformDescriptionXSLTSourceURL = resolve( platformDescriptionXSLTSource ); 470 URL sensorDescriptionXSLTSourceURL = resolve( sensorDescriptionXSLTSource ); 471 472 SourceServerConfiguration config = new SourceServerConfiguration( id, service, version, ows, 473 platformDescriptionFeatureType, 474 platformDescriptionIdPropertyName, 475 platformDescriptionCoordPropertyName, 476 platformDescriptionXSLTSourceURL, 477 sensorDescriptionFeatureType, 478 sensorDescriptionIdPropertyName, 479 sensorDescriptionXSLTSourceURL ); 480 481 if ( sourceServers.contains( config ) ) { 482 LOG.logWarning( "SourceServer with id '" + id + "' exists! It won't be added again!" ); 483 484 } else { 485 sourceServers.add( config ); 486 } 487 } 488 489 SourceServerConfiguration[] ssc = new SourceServerConfiguration[sourceServers.size()]; 490 return sourceServers.toArray( ssc ); 491 492 } 493 494 /** 495 * returns the URL of the data service capabilities 496 * 497 * @param node 498 * @return the URL of the data service capabilities 499 * @throws XMLParsingException 500 * @throws MalformedURLException 501 */ 502 private OGCWebService getDataServiceCapaOnlineResource( Node node ) 503 throws XMLParsingException, MalformedURLException, IOException, SAXException, 504 InvalidConfigurationException, OGCWebServiceException { 505 SimpleLink link = parseSimpleLink( (Element) node ); 506 507 Linkage linkage = new Linkage( link.getHref().toURL() ); 508 509 OGCWebService wfs = null; 510 String s = link.getHref().toURL().toExternalForm().toUpperCase(); 511 512 if ( s.startsWith( "FILE" ) ) { 513 WFSConfigurationDocument doc = new WFSConfigurationDocument(); 514 doc.load( resolve( linkage.getHref().toExternalForm() ) ); 515 wfs = WFServiceFactory.createInstance( doc.getConfiguration() ); 516 } else { 517 WFSCapabilitiesDocument doc = new WFSCapabilitiesDocument(); 518 doc.load( linkage.getHref() ); 519 wfs = new RemoteWFService( (WFSCapabilities) doc.parseCapabilities() ); 520 } 521 522 return wfs; 523 } 524 525 }