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