    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/ogcwebservices/sos/getobservation/GetObservationDocument.java $
    002
    003    /*----------------------------------------------------------------------------
    004     This file is part of deegree, http://deegree.org/
    005     Copyright (C) 2001-2009 by:
    006       Department of Geography, University of Bonn
    007     and
    008       lat/lon GmbH
    009
    010     This library is free software; you can redistribute it and/or modify it under
    011     the terms of the GNU Lesser General Public License as published by the Free
    012     Software Foundation; either version 2.1 of the License, or (at your option)
    013     any later version.
    014     This library is distributed in the hope that it will be useful, but WITHOUT
    015     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    016     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    017     details.
    018     You should have received a copy of the GNU Lesser General Public License
    019     along with this library; if not, write to the Free Software Foundation, Inc.,
    020     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    021
    022     Contact information:
    023
    024     lat/lon GmbH
    025     Aennchenstr. 19, 53177 Bonn
    026     Germany
    027     http://lat-lon.de/
    028
    029     Department of Geography, University of Bonn
    030     Prof. Dr. Klaus Greve
    031     Postfach 1147, 53001 Bonn
    032     Germany
    033     http://www.geographie.uni-bonn.de/deegree/
    034
    035     e-mail: info@deegree.org
    036    ----------------------------------------------------------------------------*/
    037    package org.deegree.ogcwebservices.sos.getobservation;
    038
    039    import java.io.IOException;
    040    import java.net.URL;
    041    import java.util.ArrayList;
    042    import java.util.HashMap;
    043    import java.util.Iterator;
    044    import java.util.List;
    045    import java.util.Map;
    046
    047    import javax.xml.transform.TransformerException;
    048
    049    import org.deegree.datatypes.QualifiedName;
    050    import org.deegree.framework.log.ILogger;
    051    import org.deegree.framework.log.LoggerFactory;
    052    import org.deegree.framework.xml.XMLParsingException;
    053    import org.deegree.framework.xml.XMLTools;
    054    import org.deegree.model.filterencoding.ComparisonOperation;
    055    import org.deegree.model.filterencoding.ComplexFilter;
    056    import org.deegree.model.filterencoding.Filter;
    057    import org.deegree.model.filterencoding.FilterConstructionException;
    058    import org.deegree.model.filterencoding.LogicalOperation;
    059    import org.deegree.model.filterencoding.Operation;
    060    import org.deegree.model.filterencoding.OperationDefines;
    061    import org.deegree.model.filterencoding.PropertyIsBetweenOperation;
    062    import org.deegree.model.filterencoding.PropertyIsCOMPOperation;
    063    import org.deegree.model.filterencoding.PropertyIsLikeOperation;
    064    import org.deegree.model.filterencoding.PropertyIsNullOperation;
    065    import org.deegree.model.filterencoding.PropertyName;
    066    import org.deegree.model.filterencoding.SpatialOperation;
    067    import org.deegree.model.spatialschema.Envelope;
    068    import org.deegree.ogcbase.OGCDocument;
    069    import org.deegree.ogcwebservices.OGCWebService;
    070    import org.deegree.ogcwebservices.OGCWebServiceException;
    071    import org.deegree.ogcwebservices.sos.WFSRequestGenerator;
    072    import org.deegree.ogcwebservices.sos.WFSRequester;
    073    import org.deegree.ogcwebservices.sos.XMLFactory;
    074    import org.deegree.ogcwebservices.sos.XSLTransformer;
    075    import org.deegree.ogcwebservices.sos.configuration.MeasurementConfiguration;
    076    import org.deegree.ogcwebservices.sos.configuration.PlatformConfiguration;
    077    import org.deegree.ogcwebservices.sos.configuration.SOSDeegreeParams;
    078    import org.deegree.ogcwebservices.sos.configuration.SensorConfiguration;
    079    import org.deegree.ogcwebservices.sos.configuration.SourceServerConfiguration;
    080    import org.deegree.ogcwebservices.sos.om.Observation;
    081    import org.deegree.ogcwebservices.sos.om.ObservationArray;
    082    import org.w3c.dom.Document;
    083    import org.w3c.dom.Node;
    084    import org.xml.sax.SAXException;
    085
    086    /**
    087     * get the observation data from the xsl transformed wfs requests
    088     *
    089     * @author <a href="mailto:mkulbe@lat-lon.de">Matthias Kulbe </a>
    090     * @author last edited by: $Author: mschneider $
    091     *
    092     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    093     */
    094    public class GetObservationDocument extends OGCDocument {
    095
    096        private static final long serialVersionUID = 4262217635140146058L;
    097
    098        private static final ILogger LOG = LoggerFactory.getLogger( XMLFactory.class );
    099
    100        private static final String XML_TEMPLATE = "GetObservationTemplate.xml";
    101
    102        /**
    103         * @throws IOException
    104         * @throws SAXException
    105         */
    106        public void createEmptyDocument()
    107                                throws IOException, SAXException {
    108            URL url = GetObservationDocument.class.getResource( XML_TEMPLATE );
    109            if ( url == null ) {
    110                throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
    111            }
    112            load( url );
    113        }
    114
    115        /**
    116         * gets the data from sensors
    117         *
    118         * @param deegreeParams
    119         * @param request
    120         * @return the data
    121         * @throws OGCWebServiceException
    122         * @throws XMLParsingException
    123         * @throws IOException
    124         * @throws SAXException
    125         * @throws TransformerException
    126         */
    127        public ObservationArray[] getObservations( SOSDeegreeParams deegreeParams, GetObservationRequest request )
    128                                throws OGCWebServiceException, XMLParsingException, TransformerException, IOException,
    129                                SAXException {
    130
    131            Envelope bbox = request.getBBox();
    132            Object[] times = request.getTime();
    133            Query query = request.getQuery();
    134            String[] platforms = request.getPlatforms();
    135            String[] sensors = request.getSensors();
    136
    137            ArrayList<String> sensorList = null;
    138
    139            if ( ( sensors.length < 1 ) && ( platforms.length < 1 ) ) {
    140
    141                String[] platformsInBbox = getPlatformsInBBoxFromServers( bbox,
    142                                                                          deegreeParams.getSourceServerConfigurations(),
    143                                                                          deegreeParams );
    144
    145                LOG.logDebug( "## found " + platformsInBbox.length + " platforms in bbox" );
    146
    147                String[] sensorsFromPlatforms = getSensorIdsFromPlatforms( platformsInBbox, deegreeParams );
    148
    149                LOG.logDebug( "## found " + sensorsFromPlatforms.length + " sensors in bbox" );
    150
    151                sensorList = new ArrayList<String>( sensorsFromPlatforms.length );
    152                for ( int i = 0; i < sensorsFromPlatforms.length; i++ ) {
    153                    if ( !sensorList.contains( sensorsFromPlatforms[i] ) ) {
    154                        sensorList.add( sensorsFromPlatforms[i] );
    155                    }
    156                }
    157            } else {
    158                LOG.logDebug( "info: found sensors and/or platforms" );
    159                // checks the position in the bbox
    160                boolean contains = areSensorsInBBox( bbox, sensors, platforms, deegreeParams );
    161
    162                if ( contains ) {
    163                    sensorList = new ArrayList<String>( 100 );
    164                    for ( int i = 0; i < sensors.length; i++ ) {
    165                        if ( !sensorList.contains( sensors[i] ) ) {
    166                            sensorList.add( sensors[i] );
    167                        }
    168                    }
    169
    170                    String[] sensorsFromPlatforms = getSensorIdsFromPlatforms( platforms, deegreeParams );
    171                    for ( int i = 0; i < sensorsFromPlatforms.length; i++ ) {
    172                        if ( !sensorList.contains( sensorsFromPlatforms[i] ) ) {
    173                            sensorList.add( sensorsFromPlatforms[i] );
    174                        }
    175                    }
    176                }
    177            }
    178
    179            ArrayList<ObservationArray> observations = new ArrayList<ObservationArray>( sensorList.size() );
    180
    181            for ( int i = 0; i < sensorList.size(); i++ ) {
    182                Document observationDocument = getObservationFromSensor( sensorList.get( i ), deegreeParams, times, query );
    183
    184                if ( observationDocument != null ) {
    185                    ObservationArray observationArray = getObservationsFromDocuments( observationDocument, bbox,
    186                                                                                      sensorList.get( i ) );
    187                    observations.add( observationArray );
    188                }
    189            }
    190
    191            LOG.logDebug( "-> have " + observations.size() + " observations collected" );
    192
    193            return observations.toArray( new ObservationArray[observations.size()] );
    194        }
    195
    196        /**
    197         * returns all platforms in the given bbox, but only from the given servers
    198         *
    199         * @param bbox
    200         * @param servers
    201         * @param params
    202         * @return all platforms in the given bbox, but only from the given servers
    203         */
    204        private String[] getPlatformsInBBoxFromServers( Envelope bbox, SourceServerConfiguration[] servers,
    205                                                        SOSDeegreeParams params )
    206                                throws OGCWebServiceException {
    207
    208            ArrayList<Document> tPDResults = new ArrayList<Document>( servers.length );
    209
    210            try {
    211                for ( int i = 0; i < servers.length; i++ ) {
    212
    213                    // only if server can provide platformmetadata
    214                    if ( servers[i].havePlatformDescriptionData() ) {
    215                        Document request = WFSRequestGenerator.createBBoxWFSRequest(
    216                                                                                     bbox,
    217                                                                                     servers[i].getPlatformDescriptionFeatureType(),
    218                                                                                     servers[i].getPlatformDescriptionCoordPropertyName() );
    219
    220                        Document result = WFSRequester.sendWFSrequest( request, servers[i].getDataService() );
    221
    222                        if ( result != null ) {
    223                            URL pdxs = servers[i].getPlatformDescriptionXSLTScriptSource();
    224                            tPDResults.add( XSLTransformer.transformDocument( result, pdxs ) );
    225                        }
    226                    }
    227
    228                }
    229            } catch ( Exception e ) {
    230                LOG.logError( "could not access platforms in BBOX from DataService ", e );
    231                throw new OGCWebServiceException( this.getClass().getName(),
    232                                                  "could not access platforms in BBOX from DataService " );
    233            }
    234
    235            Document[] docs = tPDResults.toArray( new Document[tPDResults.size()] );
    236
    237            return getPlatformIdsFromPlatformDocs( docs, params );
    238
    239        }
    240
    241        /**
    242         * returns the observationArray, with all observations, from a wfs result
    243         *
    244         * @param bbox
    245         * @return the observationArray, with all observations, from a wfs result
    246         * @throws XMLParsingException
    247         */
    248        private ObservationArray getObservationsFromDocuments( Document doc, Envelope bbox, String sensorId )
    249                                throws XMLParsingException {
    250
    251            List<Node> observations = XMLTools.getNodes( doc, "om:ObservationArray/om:observationMembers/gml:Observation",
    252                                                         nsContext );
    253
    254            if ( observations.size() < 1 ) {
    255                LOG.logDebug( "warning: no observations found in document" );
    256            }
    257
    258            ArrayList<Observation> observationsList = new ArrayList<Observation>( observations.size() );
    259
    260            for ( int i = 0; i < observations.size(); i++ ) {
    261
    262                String timeStamp = XMLTools.getRequiredNodeAsString( observations.get( i ),
    263                                                                     "./gml:timeStamp/gml:TimeInstant/gml:timePosition",
    264                                                                     nsContext );
    265
    266                String resultOf = XMLTools.getRequiredNodeAsString( observations.get( i ),
    267                                                                    "./gml:resultOf/gml:QuantityList", nsContext );
    268
    269                observationsList.add( new Observation( timeStamp, resultOf ) );
    270            }
    271
    272            LOG.logDebug( "-> ObservationArray created" );
    273            Observation[] obs = new Observation[observationsList.size()];
    274            obs = observationsList.toArray( obs );
    275            return new ObservationArray( obs, bbox, sensorId );
    276        }
    277
    278        /**
    279         * gets the observation from a sensor, by requesting the correct wfs
    280         *
    281         * @param sensor
    282         * @param params
    283         * @return the document
    284         */
    285        private Document getObservationFromSensor( String sensor, SOSDeegreeParams params, Object[] times, Query query )
    286                                throws OGCWebServiceException {
    287
    288            try {
    289                // query
    290                MeasurementConfiguration measureConfig = null;
    291                Operation filterOperation = null;
    292
    293                if ( query != null ) {
    294                    String queryFeature = query.getFeature();
    295                    measureConfig = params.getSensorConfiguration( sensor ).getMeasurementById( queryFeature );
    296                    if ( measureConfig == null ) {
    297                        throw new Exception( "warning: sensor not support the requested " + "observationFeature!" );
    298                    }
    299
    300                    // gets the filter operations
    301                    if ( query.getFilter() != null ) {
    302                        LOG.logDebug( "-> QueryFilter found" );
    303                        Operation op = query.getFilter().getOperation();
    304                        filterOperation = modifyOperation( op, measureConfig );
    305                    }
    306                } else {
    307                    // TODO
    308                    // I think this is a mistake and instead all measurements of a
    309                    // sensor has to requested from the WFS
    310                    LOG.logDebug( "warning: no query given, will use the default from sensor" );
    311                    measureConfig = params.getSensorConfiguration( sensor ).getFirstMeasurementConfiguration();
    312                    Filter filter = measureConfig.getConstraint();
    313                    if ( filter != null ) {
    314                        filterOperation = ( (ComplexFilter) filter ).getOperation();
    315                    }
    316                }
    317
    318                Document request = WFSRequestGenerator.createObservationWFSRequest( times,
    319                                                                                    measureConfig.getFeatureTypeName(),
    320                                                                                    measureConfig.getTimePropertyName(),
    321                                                                                    filterOperation );
    322
    323                SensorConfiguration sc = params.getSensorConfiguration( sensor );
    324                String ssID = sc.getFirstMeasurementConfiguration().getSourceServerId();
    325                OGCWebService ows = params.getSourceServerConfiguration( ssID ).getDataService();
    326
    327                Document result = WFSRequester.sendWFSrequest( request, ows );
    328
    329                return XSLTransformer.transformDocument( result, measureConfig.getXSLTScriptSource() );
    330            } catch ( Exception e ) {
    331                LOG.logError( e.getMessage(), e );
    332                throw new OGCWebServiceException( this.getClass().getName(), "could not access observations from sensor" );
    333            }
    334
    335        }
    336
    337        /**
    338         * gets all sensorIds from the given platforms
    339         *
    340         * @param platforms
    341         * @param params
    342         * @return the ids
    343         */
    344        private String[] getSensorIdsFromPlatforms( String[] platforms, SOSDeegreeParams params )
    345                                throws OGCWebServiceException {
    346
    347            // gets all servers which have to request
    348            ArrayList<Document> transformedResultDocs = null;
    349            try {
    350                Map<String, ArrayList<String>> servers = new HashMap<String, ArrayList<String>>( platforms.length );
    351
    352                for ( int t = 0; t < platforms.length; t++ ) {
    353                    String sourceServerId = params.getPlatformConfiguration( platforms[t] ).getSourceServerId();
    354
    355                    // server schon in liste; nur platform hinzuf�gen
    356                    if ( servers.containsKey( sourceServerId ) ) {
    357                        servers.get( sourceServerId ).add( platforms[t] );
    358                    }
    359                    // server nicht in liste; server hinzuf�gen und platform hinzuf�gen
    360                    else {
    361                        ArrayList<String> temp = new ArrayList<String>( 10 );
    362                        temp.add( platforms[t] );
    363                        servers.put( sourceServerId, temp );
    364                    }
    365                }
    366
    367                transformedResultDocs = new ArrayList<Document>( servers.keySet().size() );
    368
    369                Iterator<String> iter = servers.keySet().iterator();
    370                while ( iter.hasNext() ) {
    371                    String key = iter.next();
    372                    List<String> list = servers.get( key );
    373
    374                    String[] idProps = new String[list.size()];
    375                    for ( int a = 0; a < list.size(); a++ ) {
    376                        idProps[a] = params.getPlatformConfiguration( list.get( a ) ).getIdPropertyValue();
    377                    }
    378
    379                    QualifiedName pdft = params.getSourceServerConfiguration( key ).getPlatformDescriptionFeatureType();
    380                    QualifiedName pdid = params.getSourceServerConfiguration( key ).getPlatformDescriptionIdPropertyName();
    381                    Document request = WFSRequestGenerator.createIsLikeOperationWFSRequest( idProps, pdft, pdid );
    382
    383                    OGCWebService ows = params.getSourceServerConfiguration( key ).getDataService();
    384                    Document result = WFSRequester.sendWFSrequest( request, ows );
    385
    386                    if ( result != null ) {
    387                        SourceServerConfiguration ssc = params.getSourceServerConfiguration( key );
    388                        URL url = ssc.getPlatformDescriptionXSLTScriptSource();
    389                        transformedResultDocs.add( XSLTransformer.transformDocument( result, url ) );
    390                    }
    391                }
    392            } catch ( Exception e ) {
    393                LOG.logError( e.getMessage(), e );
    394                throw new OGCWebServiceException( this.getClass().getName(), "could not access sensorsIDs from platforms " );
    395            }
    396
    397            Document[] docs = new Document[transformedResultDocs.size()];
    398            docs = transformedResultDocs.toArray( docs );
    399            return getSensorIdsFromCarriesInPlatformDoc( docs, params );
    400        }
    401
    402        /**
    403         * returns true if all Sensor and/or Platforms inside the given BBox
    404         *
    405         *
    406         * @param bbox
    407         *            null is not allowed
    408         * @param sensorIds
    409         * @param platformIds
    410         * @return <code>true</code> if all Sensor and/or Platforms inside the given BBox
    411         * @throws IOException
    412         * @throws XMLParsingException
    413         * @throws TransformerException
    414         * @throws IOException
    415         * @throws SAXException
    416         * @throws OGCWebServiceException
    417         */
    418        private boolean areSensorsInBBox( Envelope bbox, String[] sensorIds, String[] platformIds,
    419                                          SOSDeegreeParams deegreeParams )
    420                                throws OGCWebServiceException, XMLParsingException, TransformerException, IOException,
    421                                SAXException {
    422            if ( bbox == null ) {
    423                throw new NullPointerException( "bbox must be set" );
    424            }
    425
    426            // sensor and platforms
    427            if ( ( sensorIds != null ) && ( platformIds != null ) ) {
    428                if ( ( areSensorsInBBox( sensorIds, bbox, deegreeParams ) )
    429                     && ( arePlatformsInBBox( platformIds, bbox, deegreeParams ) ) ) {
    430                    return true;
    431                }
    432            } else if ( sensorIds != null && areSensorsInBBox( sensorIds, bbox, deegreeParams ) ) {
    433                // only sensors
    434                return true;
    435            } else if ( platformIds != null && arePlatformsInBBox( platformIds, bbox, deegreeParams ) ) {
    436                // only platforms
    437                return true;
    438            }
    439
    440            return false;
    441        }
    442
    443        /**
    444         * returns true, if the given sensors in bbox
    445         *
    446         * @param sensors
    447         * @param bbox
    448         * @param deegreeParams
    449         * @return <code>true</code>, if the given sensors in bbox
    450         * @throws OGCWebServiceException
    451         * @throws XMLParsingException
    452         * @throws TransformerException
    453         * @throws IOException
    454         * @throws SAXException
    455         */
    456        private boolean areSensorsInBBox( String[] sensors, Envelope bbox, SOSDeegreeParams deegreeParams )
    457                                throws OGCWebServiceException, XMLParsingException, TransformerException, IOException,
    458                                SAXException {
    459
    460            // gets all servers which have to request
    461            Map<String, ArrayList<String>> servers = new HashMap<String, ArrayList<String>>( sensors.length );
    462
    463            for ( int t = 0; t < sensors.length; t++ ) {
    464                String sourceServerId = deegreeParams.getSensorConfiguration( sensors[t] ).getSourceServerId();
    465
    466                if ( servers.containsKey( sourceServerId ) ) {
    467                    servers.get( sourceServerId ).add( sensors[t] );
    468                } else {
    469                    ArrayList<String> temp = new ArrayList<String>();
    470                    temp.add( sensors[t] );
    471                    servers.put( sourceServerId, temp );
    472                }
    473
    474            }
    475
    476            String[] keySet = servers.keySet().toArray( new String[servers.keySet().size()] );
    477            ArrayList<Document> transformedWFSResults = new ArrayList<Document>( keySet.length );
    478
    479            // process all servers in the hashTable
    480            for ( int i = 0; i < keySet.length; i++ ) {
    481
    482                Document result = getSensors( deegreeParams, servers, keySet, i );
    483
    484                // if the result is not null, transform it and add it to the result
    485                // document list
    486                if ( result != null ) {
    487                    SourceServerConfiguration ssc = deegreeParams.getSourceServerConfiguration( keySet[i] );
    488                    URL url = ssc.getSensorDescriptionXSLTScriptSource();
    489                    Document doc = XSLTransformer.transformDocument( result, url );
    490                    transformedWFSResults.add( doc );
    491                }
    492
    493            }
    494
    495            Document[] docs = new Document[transformedWFSResults.size()];
    496            docs = transformedWFSResults.toArray( docs );
    497            String[] platformList = getPlatformIdsFromAttachedToInSensorDocs( docs, deegreeParams );
    498
    499            if ( arePlatformsInBBox( platformList, bbox, deegreeParams ) ) {
    500                return true;
    501            }
    502            return false;
    503        }
    504
    505        private Document getSensors( SOSDeegreeParams deegreeParams, Map<String, ArrayList<String>> servers,
    506                                     String[] keySet, int i )
    507                                throws OGCWebServiceException {
    508            Document result = null;
    509            try {
    510                String[] tmp = new String[servers.get( keySet[i] ).size()];
    511                ArrayList<String> al = servers.get( keySet[i] );
    512                String[] sensorIds = al.toArray( tmp );
    513
    514                String[] sensorIdPropertyValues = new String[sensorIds.length];
    515
    516                for ( int x = 0; x < sensorIds.length; x++ ) {
    517                    sensorIdPropertyValues[i] = deegreeParams.getSensorConfiguration( sensorIds[x] ).getIdPropertyValue();
    518                }
    519
    520                SourceServerConfiguration ssc = deegreeParams.getSourceServerConfiguration( keySet[i] );
    521                QualifiedName sdft = ssc.getSensorDescriptionFeatureType();
    522                QualifiedName sdpn = ssc.getSensorDescriptionIdPropertyName();
    523                // generates the request for the current wfs
    524                Document request = WFSRequestGenerator.createIsLikeOperationWFSRequest( sensorIdPropertyValues, sdft, sdpn );
    525                // sends the request to the current wfs
    526                result = WFSRequester.sendWFSrequest( request, ssc.getDataService() );
    527            } catch ( Exception e ) {
    528                LOG.logError( e.getMessage(), e );
    529                throw new OGCWebServiceException( this.getClass().getName(), "could not evaluate "
    530                                                                             + "if platform is contained in BBOX" );
    531            }
    532            return result;
    533        }
    534
    535        /**
    536         * checks if the platforms inside the bbox
    537         *
    538         * @param platformIds
    539         * @param bbox
    540         * @return the check result
    541         * @throws OGCWebServiceException
    542         */
    543        private boolean arePlatformsInBBox( String[] platformIds, Envelope bbox, SOSDeegreeParams deegreeParams )
    544                                throws OGCWebServiceException {
    545
    546            ArrayList<SourceServerConfiguration> serverConfigsList = new ArrayList<SourceServerConfiguration>();
    547
    548            // gets all platforms in bbox, only from neccessary servers
    549            for ( int i = 0; i < platformIds.length; i++ ) {
    550                String id = deegreeParams.getPlatformConfiguration( platformIds[i] ).getSourceServerId();
    551                SourceServerConfiguration ssc = deegreeParams.getSourceServerConfiguration( id );
    552                if ( !serverConfigsList.contains( ssc ) ) {
    553                    serverConfigsList.add( ssc );
    554                }
    555            }
    556
    557            SourceServerConfiguration[] ssc = new SourceServerConfiguration[serverConfigsList.size()];
    558            ssc = serverConfigsList.toArray( ssc );
    559            String[] platformsInBBox = getPlatformsInBBoxFromServers( bbox, ssc, deegreeParams );
    560
    561            // compares platforms in bbox with the given platforms
    562            for ( int i = 0; i < platformIds.length; i++ ) {
    563                boolean found = false;
    564
    565                for ( int a = 0; a < platformsInBBox.length; a++ ) {
    566
    567                    if ( platformIds[i].equals( platformsInBBox[a] ) ) {
    568
    569                        found = true;
    570                    }
    571                }
    572                if ( !found ) {
    573                    throw new OGCWebServiceException( "Sensor or Platform not in given bbox" );
    574                }
    575            }
    576
    577            return true;
    578        }
    579
    580        /**
    581         * gets all platformIds from attachedTo parts in SensorDescriptionDocuments
    582         *
    583         */
    584        private String[] getPlatformIdsFromAttachedToInSensorDocs( Document[] docs, SOSDeegreeParams deegreeParams )
    585                                throws XMLParsingException {
    586
    587            ArrayList<String> platformIdList = new ArrayList<String>();
    588
    589            for ( int a = 0; a < docs.length; a++ ) {
    590
    591                List<Node> nl = XMLTools.getNodes( docs[a], "sml:Sensors/sml:Sensor", nsContext );
    592
    593                for ( int i = 0; i < nl.size(); i++ ) {
    594                    String platformIdPropertyValue = XMLTools.getNodeAsString( nl.get( i ),
    595                                                                               "sml:attachedTo/sml:Component/text()",
    596                                                                               nsContext, null );
    597
    598                    PlatformConfiguration pc = deegreeParams.getPlatformConfigurationByIdPropertyValue( platformIdPropertyValue );
    599
    600                    String platformId = null;
    601                    if ( pc != null ) {
    602                        platformId = pc.getId();
    603                    }
    604
    605                    if ( platformId != null ) {
    606                        platformIdList.add( platformId );
    607                    }
    608                }
    609            }
    610
    611            return platformIdList.toArray( new String[platformIdList.size()] );
    612        }
    613
    614        /**
    615         * gets the platformIds from all PlatformDescriptionDocuments
    616         *
    617         */
    618        private String[] getPlatformIdsFromPlatformDocs( Document[] docs, SOSDeegreeParams deegreeParams )
    619                                throws OGCWebServiceException {
    620
    621            if ( docs == null ) {
    622                throw new NullPointerException( "null not allowed" );
    623            }
    624
    625            ArrayList<String> platformIdList;
    626            try {
    627
    628                platformIdList = new ArrayList<String>( docs.length );
    629                for ( int a = 0; a < docs.length; a++ ) {
    630
    631                    List<Node> itemsList = XMLTools.getNodes( docs[a], "sml:Platforms/sml:Platform", nsContext );
    632                    for ( int i = 0; i < itemsList.size(); i++ ) {
    633                        String platformIdPropertyValue = XMLTools.getRequiredNodeAsString( itemsList.get( i ), "@id",
    634                                                                                           nsContext );
    635
    636                        PlatformConfiguration pc = deegreeParams.getPlatformConfigurationByIdPropertyValue( platformIdPropertyValue );
    637
    638                        if ( pc != null ) {
    639                            platformIdList.add( pc.getId() );
    640                        }
    641                    }
    642
    643                }
    644            } catch ( Exception e ) {
    645                LOG.logError( e.getMessage(), e );
    646                throw new OGCWebServiceException( this.getClass().getName(), "could not access " + "platform IDs" );
    647            }
    648
    649            return platformIdList.toArray( new String[platformIdList.size()] );
    650
    651        }
    652
    653        /**
    654         * gets all sensorSCSId's from the given platformDescription Document
    655         *
    656         */
    657        private String[] getSensorIdsFromCarriesInPlatformDoc( Document[] docs, SOSDeegreeParams deegreeParams )
    658                                throws OGCWebServiceException {
    659
    660            try {
    661                ArrayList<String> sensorIdList = new ArrayList<String>( 100 );
    662
    663                for ( int x = 0; x < docs.length; x++ ) {
    664
    665                    List<Node> platformNodeList = XMLTools.getNodes( docs[x], "sml:Platforms/sml:Platform", nsContext );
    666
    667                    for ( int i = 0; i < platformNodeList.size(); i++ ) {
    668                        List<Node> carriesNodeList = XMLTools.getNodes( platformNodeList.get( i ), "sml:carries", nsContext );
    669
    670                        for ( int a = 0; a < carriesNodeList.size(); a++ ) {
    671                            String sensorIdPropertyValue = XMLTools.getRequiredNodeAsString( carriesNodeList.get( a ),
    672                                                                                             "sml:Asset/text()", nsContext );
    673
    674                            if ( deegreeParams.getSensorConfigurationByIdPropertyValue( sensorIdPropertyValue ) != null ) {
    675                                String sensorId = deegreeParams.getSensorConfigurationByIdPropertyValue(
    676                                                                                                         sensorIdPropertyValue ).getId();
    677
    678                                if ( sensorId != null ) {
    679                                    sensorIdList.add( sensorId );
    680                                }
    681                            }
    682                        }
    683                    }
    684                }
    685                return sensorIdList.toArray( new String[sensorIdList.size()] );
    686            } catch ( Exception e ) {
    687                LOG.logError( e.getMessage(), e );
    688                throw new OGCWebServiceException( this.getClass().getName(),
    689                                                  "could not access sensor IDs carres in platform " );
    690            }
    691        }
    692
    693        /**
    694         * returns the modified operation; modify the scs query to create the correct wfs querry
    695         *
    696         */
    697        private Operation modifyOperation( Operation operation, MeasurementConfiguration measureConfig )
    698                                throws FilterConstructionException {
    699
    700            Operation op = null;
    701            if ( operation instanceof LogicalOperation ) {
    702                LOG.logDebug( "logical operation found" );
    703                List<Operation> modOps = new ArrayList<Operation>();
    704                List<Operation> ops = ( (LogicalOperation) operation ).getArguments();
    705                for ( int i = 0; i < ops.size(); i++ ) {
    706                    modOps.add( modifyOperation( ops.get( i ), measureConfig ) );
    707                }
    708                op = new LogicalOperation( ( (LogicalOperation) operation ).getOperatorId(), modOps );
    709            } else if ( operation instanceof ComparisonOperation ) {
    710                LOG.logDebug( "comparison operation found" );
    711                op = ( getModifiedComparisonOperation( (ComparisonOperation) operation, measureConfig ) );
    712            } else if ( operation instanceof SpatialOperation ) {
    713                LOG.logDebug( "spatial operation not supported!" );
    714            }
    715
    716            Filter filter = measureConfig.getConstraint();
    717            if ( filter != null ) {
    718                // adds a predefined constraint taken from the measurements
    719                // configuration
    720                Operation constraint = ( (ComplexFilter) filter ).getOperation();
    721                if ( op != null ) {
    722                    ArrayList<Operation> ar = new ArrayList<Operation>( 2 );
    723                    ar.add( constraint );
    724                    ar.add( op );
    725                    op = new LogicalOperation( OperationDefines.AND, ar );
    726                } else {
    727                    op = constraint;
    728                }
    729            }
    730
    731            return op;
    732        }
    733
    734        /**
    735         * returns the modified ComparisonOperation
    736         *
    737         */
    738        private Operation getModifiedComparisonOperation( ComparisonOperation compOp,
    739                                                          MeasurementConfiguration measuresConfig ) {
    740
    741            if ( compOp instanceof PropertyIsBetweenOperation ) {
    742                LOG.logDebug( "PropertyIsBetweenOperation found" );
    743                // FIXME if function is supported by your wfs; use it! instead of
    744                // this
    745                ArrayList<Operation> temp = new ArrayList<Operation>();
    746                // set the lower boundary
    747                temp.add( new PropertyIsCOMPOperation( OperationDefines.PROPERTYISGREATERTHAN,
    748                                                       new PropertyName( measuresConfig.getMeasurandPropertyName() ),
    749                                                       ( (PropertyIsBetweenOperation) compOp ).getLowerBoundary() ) );
    750                // set the upper boundary
    751                temp.add( new PropertyIsCOMPOperation( OperationDefines.PROPERTYISLESSTHAN,
    752                                                       new PropertyName( measuresConfig.getMeasurandPropertyName() ),
    753                                                       ( (PropertyIsBetweenOperation) compOp ).getUpperBoundary() ) );
    754                return new LogicalOperation( OperationDefines.AND, temp );
    755
    756            } else if ( compOp instanceof PropertyIsCOMPOperation ) {
    757                LOG.logDebug( "PropertyIsCompOperation found" );
    758                // returns a PropertyIsCOMPOperation with modified PropertyName
    759                return new PropertyIsCOMPOperation( compOp.getOperatorId(),
    760                                                    new PropertyName( measuresConfig.getMeasurandPropertyName() ),
    761                                                    ( (PropertyIsCOMPOperation) compOp ).getSecondExpression() );
    762
    763            } else if ( compOp instanceof PropertyIsLikeOperation ) {
    764                LOG.logDebug( "PropertyIsLike found" );
    765                // returns a PropertyIsLikeOperation with modified PropertyName
    766                return new PropertyIsLikeOperation( new PropertyName( measuresConfig.getMeasurandPropertyName() ),
    767                                                    ( (PropertyIsLikeOperation) compOp ).getLiteral(),
    768                                                    ( (PropertyIsLikeOperation) compOp ).getWildCard(),
    769                                                    ( (PropertyIsLikeOperation) compOp ).getSingleChar(),
    770                                                    ( (PropertyIsLikeOperation) compOp ).getEscapeChar() );
    771
    772            } else if ( compOp instanceof PropertyIsNullOperation ) {
    773                LOG.logDebug( "PropertyIsNull is not supported!" );
    774            }
    775
    776            return null;
    777        }
    778    }