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