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