001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/sos/getobservation/GetObservationRequest.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2008 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstraße 19  
030     53177 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     lat/lon GmbH
036     Aennchenstraße 19
037     53177 Bonn
038     Germany
039     E-Mail: greve@giub.uni-bonn.de
040    
041     ---------------------------------------------------------------------------*/
042    package org.deegree.ogcwebservices.sos.getobservation;
043    
044    import java.util.ArrayList;
045    import java.util.List;
046    import java.util.Map;
047    
048    import org.deegree.framework.log.ILogger;
049    import org.deegree.framework.log.LoggerFactory;
050    import org.deegree.framework.xml.NamespaceContext;
051    import org.deegree.framework.xml.XMLParsingException;
052    import org.deegree.framework.xml.XMLTools;
053    import org.deegree.model.crs.UnknownCRSException;
054    import org.deegree.model.filterencoding.ComplexFilter;
055    import org.deegree.model.filterencoding.FilterConstructionException;
056    import org.deegree.model.spatialschema.Envelope;
057    import org.deegree.model.spatialschema.GMLGeometryAdapter;
058    import org.deegree.ogcbase.CommonNamespaces;
059    import org.deegree.ogcwebservices.AbstractOGCWebServiceRequest;
060    import org.deegree.ogcwebservices.OGCWebServiceException;
061    import org.w3c.dom.Document;
062    import org.w3c.dom.Element;
063    import org.w3c.dom.Node;
064    
065    /**
066     * represent a getObservation request
067     * 
068     * @author <a href="mailto:mkulbe@lat-lon.de">Matthias Kulbe </a>
069     * 
070     * @version 1.0
071     */
072    
073    public class GetObservationRequest extends AbstractOGCWebServiceRequest {
074    
075        private static final NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
076    
077        private static final ILogger LOG = LoggerFactory.getLogger( GetObservationRequest.class );
078    
079        private Envelope envelope = null;
080    
081        private Query query = null;
082    
083        private Object[] time = null;
084    
085        private String[] platforms = null;
086    
087        private String[] sensors = null;
088    
089        private String outputFormat;
090    
091        /**
092         * create a GetObservationRequest from KVP Map
093         * 
094         * @param map
095         * @return
096         * 
097         */
098        public static GetObservationRequest create( Map map ) {
099            throw new UnsupportedOperationException();
100            /*
101             * // TODO implement this? String id = null; String version = null;
102             * 
103             * String outputFormat = null; Query query = null; Envelope boundingBox = null; Object[]
104             * time = null; String[] platformId = null; String[] sensorId = null;
105             * 
106             * return new GetObservationRequest( query, boundingBox, outputFormat, time, platformId,
107             * sensorId, version, id, null );
108             */
109        }
110    
111        /**
112         * create from XML Document
113         * 
114         * @param id
115         * @param doc
116         * @return
117         * @throws OGCWebServiceException
118         * 
119         */
120        public static GetObservationRequest create( String id, Document doc )
121                                throws OGCWebServiceException {
122    
123            GetObservationRequest goReq = null;
124            try {
125                // gets the version
126                String version = XMLTools.getNodeAsString( doc, "sos:GetObservation/@version", nsContext, null );
127    
128                // gets the outputFormat
129                String outputFormat = XMLTools.getNodeAsString( doc, "sos:GetObservation/@outputFormat", nsContext,
130                                                                "SWEObservation" );
131    
132                // optional, fixed to "SOS"
133                String service = XMLTools.getNodeAsString( doc, "sos:GetObservation/@service", nsContext, null );
134                if ( ( service != null ) && ( !service.equals( "SOS" ) ) ) {
135                    throw new OGCWebServiceException( "service must be 'SOS'" );
136                }
137    
138                // gets Bounding Box
139                Node boxNode = XMLTools.getRequiredNode( doc, "sos:GetObservation/sos:BoundingBox", nsContext );
140                Envelope env = GMLGeometryAdapter.wrapBox( (Element) boxNode, null );
141    
142                Node queryNode = XMLTools.getNode( doc, "sos:GetObservation/sos:Query", nsContext );
143                // gets Query
144                Query query = null;
145                if ( queryNode != null ) {
146                    query = createQuery( queryNode );
147                }
148    
149                List timeList = XMLTools.getNodes( doc, "sos:GetObservation/sos:time", nsContext );
150    
151                ArrayList time = getTimeList( timeList );
152    
153                // gets id's from the requested platforms
154                List platformIdList = XMLTools.getNodes( doc, "sos:GetObservation/sos:platformID", nsContext );
155                ArrayList<String> platformId = new ArrayList<String>( platformIdList.size() );
156                for ( int i = 0; i < platformIdList.size(); i++ ) {
157                    platformId.add( XMLTools.getRequiredNodeAsString( (Node) platformIdList.get( i ), "text()", nsContext ) );
158                }
159    
160                LOG.logDebug( "Platforms=" + platformId.size() );
161    
162                // gets id's from the requested sensors
163                List sensorIdList = XMLTools.getNodes( doc, "sos:GetObservation/sos:sensorID", nsContext );
164                ArrayList<String> sensorId = new ArrayList<String>( sensorIdList.size() );
165                for ( int i = 0; i < sensorIdList.size(); i++ ) {
166                    sensorId.add( XMLTools.getRequiredNodeAsString( (Node) sensorIdList.get( i ), "text()", nsContext ) );
167                }
168                LOG.logDebug( "Sensors=" + sensorId.size() );
169    
170                goReq = new GetObservationRequest( query, env, outputFormat, time.toArray(),
171                                                   platformId.toArray( new String[platformId.size()] ),
172                                                   sensorId.toArray( new String[sensorId.size()] ), version, id, null );
173    
174            } catch ( XMLParsingException e ) {
175                e.printStackTrace();
176                throw new OGCWebServiceException( "scs webservice failure" );
177            } catch ( UnknownCRSException e ) {
178                e.printStackTrace();
179                throw new OGCWebServiceException( "scs webservice failure" );
180            }
181            return goReq;
182        }
183    
184        /**
185         * @param nsContext
186         * @param timeList
187         * @return
188         * @throws XMLParsingException
189         * @throws OGCWebServiceException
190         */
191        private static ArrayList<Object> getTimeList( List timeList )
192                                throws XMLParsingException, OGCWebServiceException {
193    
194            ArrayList<Object> time = new ArrayList<Object>( timeList.size() );
195            for ( int i = 0; i < timeList.size(); i++ ) {
196    
197                if ( ( XMLTools.getNode( (Node) timeList.get( i ), "gml:TPeriod", nsContext ) ) != null ) {
198    
199                    String begin = XMLTools.getNodeAsString( (Node) timeList.get( i ),
200                                                             "gml:TPeriod/gml:begin/gml:TInstant/gml:tPosition/text()",
201                                                             nsContext, null );
202                    if ( begin == null ) {
203                        throw new OGCWebServiceException( "TPeriod must have a begin time Position" );
204                    }
205    
206                    String end = XMLTools.getNodeAsString( (Node) timeList.get( i ),
207                                                           "gml:TPeriod/gml:end/gml:TInstant/gml:tPosition/text()",
208                                                           nsContext, null );
209                    if ( end == null ) {
210                        throw new OGCWebServiceException( "TPeriod must have a end time Position" );
211                    }
212    
213                    LOG.logDebug( "create TPeriod with begin=" + begin + " end=" + end );
214                    time.add( new TPeriod( begin, end ) );
215                } else if ( ( XMLTools.getNode( (Node) timeList.get( i ), "gml:TInstant", nsContext ) ) != null ) {
216    
217                    String temp = XMLTools.getNodeAsString( (Node) timeList.get( i ), "gml:TInstant/gml:tPosition/text()",
218                                                            nsContext, null );
219                    if ( temp == null ) {
220                        throw new OGCWebServiceException( "TInstant must have a time Position" );
221                    }
222    
223                    LOG.logDebug( "create TInstant with time=" + temp );
224                    time.add( new TInstant( temp ) );
225                } else {
226                    throw new OGCWebServiceException( "time must have a TPeriod or a TInstant" );
227                }
228            }
229            return time;
230        }
231    
232        /**
233         * @param nsContext
234         * @param queryNode
235         * @return
236         * @throws XMLParsingException
237         * @throws OGCWebServiceException
238         */
239        private static Query createQuery( Node queryNode )
240                                throws XMLParsingException, OGCWebServiceException {
241    
242            String feature = XMLTools.getRequiredNodeAsString( queryNode, "@typeName", nsContext );
243            Element filterElement = XMLTools.getChildElement( queryNode, "ogc:Filter" );
244            ComplexFilter filter = null;
245            if ( filterElement != null ) {
246                try {
247                    filter = (ComplexFilter) ComplexFilter.buildFromDOM( filterElement );
248                } catch ( FilterConstructionException e ) {
249                    e.printStackTrace();
250                    throw new OGCWebServiceException( "sos:Query is not valid!" );
251                }
252            }
253            return new Query( feature, filter );
254        }
255    
256        /**
257         * @param id
258         * @param version
259         * @param sensorId
260         * @param platformId
261         * @param time
262         * @param boundingBox
263         * @param query
264         * @param outputFormat
265         * 
266         */
267        public static void create( String id, String version, String[] sensorId, String[] platformId, Object[] time,
268                                   Envelope boundingBox, Query query, String outputFormat ) {
269            throw new UnsupportedOperationException();
270        }
271    
272        /**
273         * @param query
274         * @param boundingBox
275         * @param outputFormat
276         * @param time
277         * @param platformId
278         * @param sensorId
279         * @param version
280         * @param id
281         * 
282         */
283        private GetObservationRequest( Query query, Envelope envelope, String outputFormat, Object[] time,
284                                       String[] platformId, String[] sensorId, String version, String id,
285                                       Map<String, String> vendorSpecificParameter ) {
286    
287            super( version, id, vendorSpecificParameter );
288    
289            this.envelope = envelope;
290            this.query = query;
291            this.time = time;
292            this.platforms = platformId;
293            this.sensors = sensorId;
294            this.outputFormat = outputFormat;
295        }
296    
297        /**
298         * fixed 'SOS'
299         * 
300         * @return the String "SOS".
301         */
302        public String getServiceName() {
303            return "SOS";
304        }
305    
306        /**
307         * @return
308         */
309        public Envelope getBBox() {
310            return envelope;
311        }
312    
313        /**
314         * @return platforms
315         */
316        public String[] getPlatforms() {
317            return platforms;
318        }
319    
320        /**
321         * @return query
322         */
323        public Query getQuery() {
324            return query;
325        }
326    
327        /**
328         * @return sensors
329         */
330        public String[] getSensors() {
331            return sensors;
332        }
333    
334        /**
335         * @return time
336         */
337        public Object[] getTime() {
338            return time;
339        }
340    
341        /**
342         * @return outputFormat
343         */
344        public String getOutputFormat() {
345            return outputFormat;
346        }
347    }