001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/sos/WFSRequestGenerator.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;
043    
044    import java.io.IOException;
045    import java.io.InputStream;
046    import java.util.ArrayList;
047    
048    import javax.xml.parsers.ParserConfigurationException;
049    
050    import org.deegree.datatypes.QualifiedName;
051    import org.deegree.framework.xml.NamespaceContext;
052    import org.deegree.framework.xml.XMLParsingException;
053    import org.deegree.framework.xml.XMLTools;
054    import org.deegree.model.filterencoding.ComplexFilter;
055    import org.deegree.model.filterencoding.Filter;
056    import org.deegree.model.filterencoding.Literal;
057    import org.deegree.model.filterencoding.LogicalOperation;
058    import org.deegree.model.filterencoding.Operation;
059    import org.deegree.model.filterencoding.OperationDefines;
060    import org.deegree.model.filterencoding.PropertyIsCOMPOperation;
061    import org.deegree.model.filterencoding.PropertyIsLikeOperation;
062    import org.deegree.model.filterencoding.PropertyName;
063    import org.deegree.model.filterencoding.SpatialOperation;
064    import org.deegree.model.spatialschema.Envelope;
065    import org.deegree.model.spatialschema.Geometry;
066    import org.deegree.model.spatialschema.GeometryException;
067    import org.deegree.model.spatialschema.GeometryFactory;
068    import org.deegree.ogcbase.CommonNamespaces;
069    import org.deegree.ogcwebservices.sos.getobservation.TInstant;
070    import org.deegree.ogcwebservices.sos.getobservation.TPeriod;
071    import org.w3c.dom.Document;
072    import org.w3c.dom.Element;
073    import org.xml.sax.SAXException;
074    
075    /**
076     * generate the wfs requests
077     * 
078     * @author <a href="mailto:mkulbe@lat-lon.de">Matthias Kulbe </a>
079     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
080     * 
081     */
082    
083    public class WFSRequestGenerator {
084    
085        private static final String XML_TEMPLATE = "RequestFrame.xml";
086    
087        private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
088    
089        /**
090         * cerates an empty WFS request
091         * 
092         * @return
093         * @throws IOException
094         * @throws SAXException
095         */
096        private static Document getEmptyWFSRequest()
097                                throws IOException, SAXException {
098    
099            InputStream is = WFSRequestGenerator.class.getResourceAsStream( XML_TEMPLATE );
100            if ( is == null ) {
101                throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
102            }
103    
104            return XMLTools.parse( is );
105    
106        }
107    
108        /**
109         * sets the QueryTypname in the WFS request
110         * 
111         * @param doc
112         *            representing GetFeature DOM-Object
113         * @param typename
114         * @throws ParserConfigurationException
115         * @throws XMLParsingException
116         */
117        private static void setQueryTypeName( Document doc, QualifiedName typename )
118                                throws XMLParsingException {
119    
120            Element query = (Element) XMLTools.getRequiredNode( doc, "wfs:GetFeature/wfs:Query", nsContext );
121            query.setAttribute( "xmlns:" + typename.getPrefix(), typename.getNamespace().toASCIIString() );
122            query.setAttribute( "typeName", typename.getPrefix() + ':' + typename.getLocalName() );
123        }
124    
125        /**
126         * sets a filter to the document
127         * 
128         * @param doc
129         * @param filter
130         * @throws ParserConfigurationException
131         * @throws XMLParsingException
132         */
133        private static void setFilter( Document doc, Filter filter )
134                                throws XMLParsingException {
135    
136            Element query = (Element) XMLTools.getNode( doc, "wfs:GetFeature/wfs:Query", nsContext );
137    
138            org.deegree.model.filterencoding.XMLFactory.appendFilter( query, filter );
139    
140        }
141    
142        /**
143         * creates a WFS Request with one or more isLike Operations
144         * 
145         * @param literals
146         * @param featureType
147         * @param propertyName
148         * @return
149         * @throws IOException
150         * @throws SAXException
151         * @throws ParserConfigurationException
152         * @throws XMLParsingException
153         */
154        public static Document createIsLikeOperationWFSRequest( String[] literals, QualifiedName featureType,
155                                                                QualifiedName propertyName )
156                                throws IOException, SAXException, XMLParsingException {
157    
158            if ( ( literals == null ) || ( featureType == null ) || ( propertyName == null ) ) {
159                String msg = "error: literals, featureType and propertyName can't be null";
160                throw new IllegalArgumentException( msg );
161            }
162    
163            Document request = WFSRequestGenerator.getEmptyWFSRequest();
164    
165            WFSRequestGenerator.setQueryTypeName( request, featureType );
166    
167            ArrayList al = new ArrayList();
168    
169            for ( int i = 0; i < literals.length; i++ ) {
170    
171                al.add( new PropertyIsLikeOperation( new PropertyName( propertyName ), new Literal( literals[i] ), '*',
172                                                     '#', '!' ) );
173            }
174    
175            // wenn nur ein feature abgefragt wird, dass <or> weglassen
176            if ( al.size() == 1 ) {
177                Filter filter = new ComplexFilter( ( (PropertyIsLikeOperation) al.get( 0 ) ) );
178                WFSRequestGenerator.setFilter( request, filter );
179            } else if ( al.size() > 1 ) {
180                LogicalOperation lop = new LogicalOperation( OperationDefines.OR, al );
181                WFSRequestGenerator.setFilter( request, new ComplexFilter( lop ) );
182            }
183    
184            return request;
185    
186        }
187    
188        public static Document createBBoxWFSRequest( Envelope bbox, QualifiedName featureTypeName,
189                                                     QualifiedName coordPropertyName )
190                                throws IOException, SAXException, XMLParsingException, GeometryException {
191            if ( ( bbox == null ) && ( featureTypeName == null ) && ( coordPropertyName == null ) ) {
192                String msg = "error: bbox, featureType and coordPropertyName can't be null";
193                throw new IllegalArgumentException( msg );
194            }
195    
196            Document request = WFSRequestGenerator.getEmptyWFSRequest();
197    
198            WFSRequestGenerator.setQueryTypeName( request, featureTypeName );
199    
200            Geometry geom = GeometryFactory.createSurface( bbox, null );
201    
202            SpatialOperation bboxOperation = new SpatialOperation( OperationDefines.BBOX,
203                                                                   new PropertyName( coordPropertyName ), geom );
204    
205            ComplexFilter filter = new ComplexFilter( bboxOperation );
206            WFSRequestGenerator.setFilter( request, filter );
207    
208            return request;
209        }
210    
211        /**
212         * 
213         * @param times
214         * @param featureTypeName
215         * @param timePropertyName
216         * @param filterOperation
217         * @return
218         * @throws IOException
219         * @throws SAXException
220         * @throws ParserConfigurationException
221         * @throws XMLParsingException
222         */
223        public static Document createObservationWFSRequest( Object[] times, QualifiedName featureTypeName,
224                                                            QualifiedName timePropertyName, Operation filterOperation )
225                                throws IOException, SAXException, XMLParsingException {
226    
227            if ( ( times == null ) || ( featureTypeName == null ) || ( timePropertyName == null ) ) {
228                String msg = "error: times, featureType and timePropertyName can't be null";
229                throw new IllegalArgumentException( msg );
230            }
231    
232            Document request = WFSRequestGenerator.getEmptyWFSRequest();
233    
234            WFSRequestGenerator.setQueryTypeName( request, featureTypeName );
235    
236            ArrayList timeOperationList = new ArrayList();
237    
238            // creates the time Filters
239            for ( int i = 0; i < times.length; i++ ) {
240                // if TInstant
241                if ( times[i] instanceof TInstant ) {
242                    Operation op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISEQUALTO,
243                                                                new PropertyName( timePropertyName ),
244                                                                new Literal( ( (TInstant) times[i] ).getTPosition() ) );
245                    timeOperationList.add( op );
246                    // if TPeriod
247                } else if ( times[i] instanceof TPeriod ) {
248    
249                    ArrayList al = new ArrayList();
250                    Operation op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISGREATERTHANOREQUALTO,
251                                                                new PropertyName( timePropertyName ),
252                                                                new Literal( ( (TPeriod) times[i] ).getBegin() ) );
253                    al.add( op );
254                    op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISLESSTHANOREQUALTO,
255                                                      new PropertyName( timePropertyName ),
256                                                      new Literal( ( (TPeriod) times[i] ).getEnd() ) );
257                    al.add( op );
258                    timeOperationList.add( new LogicalOperation( OperationDefines.AND, al ) );
259                }
260            }
261    
262            Operation timeOp = null;
263            // connect time operations by <or>
264            if ( timeOperationList.size() == 1 ) {
265                timeOp = (Operation) timeOperationList.get( 0 );
266            } else if ( timeOperationList.size() > 1 ) {
267                timeOp = new LogicalOperation( OperationDefines.OR, timeOperationList );
268            }
269    
270            // sets the filter by operations
271            if ( ( timeOp != null ) && ( filterOperation != null ) ) {
272                ArrayList operationList = new ArrayList();
273                operationList.add( timeOp );
274                operationList.add( filterOperation );
275    
276                Filter filter = new ComplexFilter( new LogicalOperation( OperationDefines.AND, operationList ) );
277                WFSRequestGenerator.setFilter( request, filter );
278            } else if ( timeOp != null ) {
279                WFSRequestGenerator.setFilter( request, new ComplexFilter( timeOp ) );
280            } else if ( filterOperation != null ) {
281                WFSRequestGenerator.setFilter( request, new ComplexFilter( filterOperation ) );
282            }
283    
284            return request;
285        }
286    
287    }