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    }