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 }