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 }