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    }