001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/sos/WFSRequestGenerator.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2006 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: fitzke@lat-lon.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",
121                                                                nsContext );
122            query.setAttribute( "xmlns:" + typename.getPrefix(),
123                                typename.getNamespace().toASCIIString() );
124            query.setAttribute( "typeName", typename.getPrefix() + ':' + typename.getLocalName() );
125        }
126    
127        /**
128         * sets a filter to the document
129         * 
130         * @param doc
131         * @param filter
132         * @throws ParserConfigurationException
133         * @throws XMLParsingException
134         */
135        private static void setFilter( Document doc, Filter filter )
136                                throws XMLParsingException {
137    
138            Element query = (Element) XMLTools.getNode( doc, "wfs:GetFeature/wfs:Query", nsContext );
139    
140            org.deegree.model.filterencoding.XMLFactory.appendFilter( query, filter );
141    
142        }
143    
144        /**
145         * creates a WFS Request with one or more isLike Operations
146         * 
147         * @param literals
148         * @param featureType
149         * @param propertyName
150         * @return
151         * @throws IOException
152         * @throws SAXException
153         * @throws ParserConfigurationException
154         * @throws XMLParsingException
155         */
156        public static Document createIsLikeOperationWFSRequest( String[] literals,
157                                                               QualifiedName featureType,
158                                                               QualifiedName propertyName )
159                                throws IOException, SAXException, XMLParsingException {
160    
161            if ( ( literals == null ) || ( featureType == null ) || ( propertyName == null ) ) {
162                String msg = "error: literals, featureType and propertyName can't be null";
163                throw new IllegalArgumentException( msg );
164            }
165    
166            Document request = WFSRequestGenerator.getEmptyWFSRequest();
167    
168            WFSRequestGenerator.setQueryTypeName( request, featureType );
169    
170            ArrayList al = new ArrayList();
171    
172            for ( int i = 0; i < literals.length; i++ ) {
173    
174                al.add( new PropertyIsLikeOperation( new PropertyName( propertyName ),
175                                                     new Literal( literals[i] ), '*', '#', '!' ) );
176            }
177    
178            // wenn nur ein feature abgefragt wird, dass <or> weglassen
179            if ( al.size() == 1 ) {
180                Filter filter = new ComplexFilter( ( (PropertyIsLikeOperation) al.get( 0 ) ) );
181                WFSRequestGenerator.setFilter( request, filter );
182            } else if ( al.size() > 1 ) {
183                LogicalOperation lop = new LogicalOperation( OperationDefines.OR, al );
184                WFSRequestGenerator.setFilter( request, new ComplexFilter( lop ) );
185            }
186    
187            return request;
188    
189        }
190    
191        public static Document createBBoxWFSRequest( Envelope bbox, QualifiedName featureTypeName,
192                                                    QualifiedName coordPropertyName )
193                                throws IOException, SAXException, XMLParsingException,
194                                GeometryException {
195            if ( ( bbox == null ) && ( featureTypeName == null ) && ( coordPropertyName == null ) ) {
196                String msg = "error: bbox, featureType and coordPropertyName can't be null";
197                throw new IllegalArgumentException( msg );
198            }
199    
200            Document request = WFSRequestGenerator.getEmptyWFSRequest();
201    
202            WFSRequestGenerator.setQueryTypeName( request, featureTypeName );
203    
204            Geometry geom = GeometryFactory.createSurface( bbox, null );
205    
206            SpatialOperation bboxOperation = new SpatialOperation(
207                                                                   OperationDefines.BBOX,
208                                                                   new PropertyName( coordPropertyName ),
209                                                                   geom );
210    
211            ComplexFilter filter = new ComplexFilter( bboxOperation );
212            WFSRequestGenerator.setFilter( request, filter );
213    
214            return request;
215        }
216    
217        /**
218         * 
219         * @param times
220         * @param featureTypeName
221         * @param timePropertyName
222         * @param filterOperation
223         * @return
224         * @throws IOException
225         * @throws SAXException
226         * @throws ParserConfigurationException
227         * @throws XMLParsingException
228         */
229        public static Document createObservationWFSRequest( Object[] times,
230                                                           QualifiedName featureTypeName,
231                                                           QualifiedName timePropertyName,
232                                                           Operation filterOperation )
233                                throws IOException, SAXException, XMLParsingException {
234    
235            if ( ( times == null ) || ( featureTypeName == null ) || ( timePropertyName == null ) ) {
236                String msg = "error: times, featureType and timePropertyName can't be null";
237                throw new IllegalArgumentException( msg );
238            }
239    
240            Document request = WFSRequestGenerator.getEmptyWFSRequest();
241    
242            WFSRequestGenerator.setQueryTypeName( request, featureTypeName );
243    
244            ArrayList timeOperationList = new ArrayList();
245    
246            // creates the time Filters
247            for ( int i = 0; i < times.length; i++ ) {
248                // if TInstant
249                if ( times[i] instanceof TInstant ) {
250                    Operation op = new PropertyIsCOMPOperation(
251                                                                OperationDefines.PROPERTYISEQUALTO,
252                                                                new PropertyName( timePropertyName ),
253                                                                new Literal(
254                                                                             ( (TInstant) times[i] ).getTPosition() ) );
255                    timeOperationList.add( op );
256                    // if TPeriod
257                } else if ( times[i] instanceof TPeriod ) {
258    
259                    ArrayList al = new ArrayList();
260                    Operation op = new PropertyIsCOMPOperation(
261                                                                OperationDefines.PROPERTYISGREATERTHANOREQUALTO,
262                                                                new PropertyName( timePropertyName ),
263                                                                new Literal(
264                                                                             ( (TPeriod) times[i] ).getBegin() ) );
265                    al.add( op );
266                    op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISLESSTHANOREQUALTO,
267                                                      new PropertyName( timePropertyName ),
268                                                      new Literal( ( (TPeriod) times[i] ).getEnd() ) );
269                    al.add( op );
270                    timeOperationList.add( new LogicalOperation( OperationDefines.AND, al ) );
271                }
272            }
273    
274            Operation timeOp = null;
275            // connect time operations by <or>
276            if ( timeOperationList.size() == 1 ) {
277                timeOp = (Operation) timeOperationList.get( 0 );
278            } else if ( timeOperationList.size() > 1 ) {
279                timeOp = new LogicalOperation( OperationDefines.OR, timeOperationList );
280            }
281    
282            // sets the filter by operations
283            if ( ( timeOp != null ) && ( filterOperation != null ) ) {
284                ArrayList operationList = new ArrayList();
285                operationList.add( timeOp );
286                operationList.add( filterOperation );
287    
288                Filter filter = new ComplexFilter( new LogicalOperation( OperationDefines.AND,
289                                                                         operationList ) );
290                WFSRequestGenerator.setFilter( request, filter );
291            } else if ( timeOp != null ) {
292                WFSRequestGenerator.setFilter( request, new ComplexFilter( timeOp ) );
293            } else if ( filterOperation != null ) {
294                WFSRequestGenerator.setFilter( request, new ComplexFilter( filterOperation ) );
295            }
296    
297            return request;
298        }
299    
300    }/* ********************************************************************
301     Changes to this class. What the people have been up to:
302     $Log$
303     Revision 1.13  2006/08/24 06:42:16  poth
304     File header corrected
305    
306     Revision 1.12  2006/08/07 12:25:14  poth
307     never thrown exceptions removed / never read variable removed
308    
309     Revision 1.11  2006/07/12 14:46:18  poth
310     comment footer added
311    
312     ********************************************************************** */