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 }