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 }