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