001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wfs/operation/Query.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 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: greve@giub.uni-bonn.de
041
042 ---------------------------------------------------------------------------*/
043 package org.deegree.ogcwebservices.wfs.operation;
044
045 import org.deegree.datatypes.QualifiedName;
046 import org.deegree.framework.xml.XMLParsingException;
047 import org.deegree.model.filterencoding.Filter;
048 import org.deegree.model.filterencoding.Function;
049 import org.deegree.ogcbase.PropertyPath;
050 import org.deegree.ogcbase.SortProperty;
051 import org.deegree.ogcwebservices.wfs.operation.GetFeature.RESULT_TYPE;
052 import org.w3c.dom.Element;
053
054 /**
055 * Represents a <code>Query</code> operation as a part of a {@link GetFeature} request.
056 *
057 * Each individual query packaged in a {@link GetFeature} request is defined using the query value.
058 * The query value defines which feature type to query, what properties to retrieve and what
059 * constraints (spatial and non-spatial) to apply to those properties.
060 * <p>
061 * The mandatory <code>typeName</code> attribute is used to indicate the name of one or more
062 * feature type instances or class instances to be queried. Its value is a list of
063 * namespace-qualified names (XML Schema type QName, e.g. myns:School) whose value must match one of
064 * the feature types advertised in the Capabilities document of the WFS. Specifying more than one
065 * typename indicates that a join operation is being performed. All the names in the typeName list
066 * must be valid types that belong to this query's feature content as defined by the GML Application
067 * Schema. Optionally, individual feature type names in the typeName list may be aliased using the
068 * format QName=Alias. The following is an example typeName value that indicates that a join
069 * operation is to be performed and includes aliases: <BR>
070 * <code>typeName="ns1:InwaterA_1m=A,ns1:InwaterA_1m=B,ns2:CoastL_1M=C"</code><BR>
071 * This example encodes a join between three feature types aliased as A, B and C. The join between
072 * feature type A and B is a self-join.
073 * </p>
074 *
075 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
076 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </a>
077 * @author last edited by: $Author: apoth $
078 *
079 * @version $Revision: 9345 $, $Date: 2007-12-27 17:22:25 +0100 (Do, 27 Dez 2007) $
080 */
081 public class Query {
082
083 private String handle;
084
085 private QualifiedName[] typeNames;
086
087 private String[] aliases;
088
089 private String featureVersion;
090
091 private String srsName;
092
093 private PropertyPath[] propertyNames;
094
095 private Function[] functions;
096
097 private Filter filter;
098
099 private SortProperty[] sortProperties;
100
101 // deegree specific extension ("inherited" from GetFeature container)
102 private RESULT_TYPE resultType;
103
104 // deegree specific extension ("inherited" from GetFeature container)
105 private int maxFeatures = -1;
106
107 // deegree specific extension ("inherited" from GetFeature container)
108 private int startPosition = 1;
109
110 /**
111 * Creates a new <code>Query</code> instance.
112 *
113 * @param propertyNames
114 * names of the requested properties, may be null or empty
115 * @param functions
116 * names of the requested functions, may be null or empty
117 * @param sortProperties
118 * sort criteria, may be null or empty
119 * @param handle
120 * client-generated identifier for the query, may be null
121 * @param featureVersion
122 * version of the feature instances to fetched, may be null
123 * @param typeNames
124 * list of requested feature types
125 * @param aliases
126 * list of aliases for the feature types, must either be null or have the same length
127 * as the typeNames array
128 * @param srsName
129 * name of the spatial reference system
130 * @param filter
131 * spatial and none-spatial constraints
132 * @param resultType
133 * deegree specific extension ("inherited" from GetFeature container)
134 * @param maxFeatures
135 * deegree specific extension ("inherited" from GetFeature container)
136 * @param startPosition
137 * deegree specific extension ("inherited" from GetFeature container)
138 */
139 Query( PropertyPath[] propertyNames, Function[] functions, SortProperty[] sortProperties, String handle,
140 String featureVersion, QualifiedName[] typeNames, String[] aliases, String srsName, Filter filter,
141 RESULT_TYPE resultType, int maxFeatures, int startPosition ) {
142 if ( propertyNames == null ) {
143 this.propertyNames = new PropertyPath[0];
144 // this.propertyNames[0] = new PropertyPath( typeNames[0] );
145 } else {
146 this.propertyNames = propertyNames;
147 }
148 this.functions = functions;
149 this.sortProperties = sortProperties;
150 this.handle = handle;
151 this.featureVersion = featureVersion;
152 this.typeNames = typeNames;
153 this.aliases = aliases;
154 assert aliases == null || aliases.length == typeNames.length;
155 this.srsName = srsName;
156 this.filter = filter;
157 this.resultType = resultType;
158 this.maxFeatures = maxFeatures;
159 this.startPosition = startPosition;
160 }
161
162 /**
163 * Creates a new <code>Query</code> instance.
164 *
165 * @param propertyNames
166 * names of the requested properties, may be null or empty
167 * @param functions
168 * names of the requested functions, may be null or empty
169 * @param sortProperties
170 * sort criteria, may be null or empty
171 * @param handle
172 * client-generated identifier for the query, may be null
173 * @param featureVersion
174 * version of the feature instances to fetched, may be null
175 * @param typeNames
176 * list of requested feature types. if more than one feature types is set a JOIN will
177 * be created (not yet supported)
178 * @param srsName
179 * name of the spatial reference system
180 * @param filter
181 * spatial and none-spatial constraints
182 * @param resultType
183 * deegree specific extension ("inherited" from GetFeature container)
184 * @param maxFeatures
185 * deegree specific extension ("inherited" from GetFeature container)
186 * @param startPosition
187 * deegree specific extension ("inherited" from GetFeature container)
188 * @return new <code>Query</code> instance
189 * @deprecated use
190 * {@link #create(PropertyPath[], Function[], SortProperty[], String, String, QualifiedName[], String, Filter, int, int, RESULT_TYPE)}
191 * instead
192 */
193 @Deprecated
194 public static Query create( PropertyPath[] propertyNames, Function[] functions, SortProperty[] sortProperties,
195 String handle, String featureVersion, QualifiedName[] typeNames, String srsName,
196 Filter filter, int maxFeatures, int startPosition, RESULT_TYPE resultType ) {
197 return new Query( propertyNames, functions, sortProperties, handle, featureVersion, typeNames, null, srsName,
198 filter, resultType, maxFeatures, startPosition );
199 }
200
201 /**
202 * Creates a new <code>Query</code> instance.
203 *
204 * @param propertyNames
205 * names of the requested properties, may be null or empty
206 * @param functions
207 * names of the requested functions, may be null or empty
208 * @param sortProperties
209 * sort criteria, may be null or empty
210 * @param handle
211 * client-generated identifier for the query, may be null
212 * @param featureVersion
213 * version of the feature instances to fetched, may be null
214 * @param typeNames
215 * list of requested feature types. if more than one feature types is set a JOIN will
216 * be created (not yet supported)
217 * @param aliases
218 * list of aliases for the feature types, must either be null or have the same length
219 * as the typeNames array
220 * @param srsName
221 * name of the spatial reference system
222 * @param filter
223 * spatial and none-spatial constraints
224 * @param resultType
225 * deegree specific extension ("inherited" from GetFeature container)
226 * @param maxFeatures
227 * deegree specific extension ("inherited" from GetFeature container)
228 * @param startPosition
229 * deegree specific extension ("inherited" from GetFeature container)
230 * @return new <code>Query</code> instance
231 */
232 public static Query create( PropertyPath[] propertyNames, Function[] functions, SortProperty[] sortProperties,
233 String handle, String featureVersion, QualifiedName[] typeNames, String[] aliases,
234 String srsName, Filter filter, int maxFeatures, int startPosition,
235 RESULT_TYPE resultType ) {
236 return new Query( propertyNames, functions, sortProperties, handle, featureVersion, typeNames, aliases,
237 srsName, filter, resultType, maxFeatures, startPosition );
238 }
239
240 /**
241 * Creates a new simple <code>Query</code> instance that selects the whole feature type.
242 *
243 * @param typeName
244 * name of the feature to be queried
245 * @return new <code>Query</code> instance
246 */
247 public static Query create( QualifiedName typeName ) {
248 return new Query( null, null, null, null, null, new QualifiedName[] { typeName }, null, null, null,
249 RESULT_TYPE.RESULTS, -1, 0 );
250 }
251
252 /**
253 * Creates a new simple <code>Query</code> instance that selects the whole feature type.
254 *
255 * @param typeName
256 * name of the feature to be queried
257 * @param filter
258 * spatial and none-spatial constraints
259 * @return new <code>Query</code> instance
260 */
261 public static Query create( QualifiedName typeName, Filter filter ) {
262 return new Query( null, null, null, null, null, new QualifiedName[] { typeName }, null, null, filter,
263 RESULT_TYPE.RESULTS, -1, 0 );
264 }
265
266 /**
267 * Creates a <code>Query</code> instance from a document that contains the DOM representation
268 * of the request, using the 1.1.0 filter encoding.
269 * <p>
270 * Note that the following attributes from the surrounding element are also considered (if it
271 * present):
272 * <ul>
273 * <li>resultType</li>
274 * <li>maxFeatures</li>
275 * <li>startPosition</li>
276 * </ul>
277 *
278 * @param element
279 * @return corresponding <code>Query</code> instance
280 * @throws XMLParsingException
281 */
282 public static Query create( Element element )
283 throws XMLParsingException {
284 return create( element, false);
285 }
286
287 /**
288 * Creates a <code>Query</code> instance from a document that contains the DOM representation
289 * of the request.
290 * <p>
291 * Note that the following attributes from the surrounding element are also considered (if it
292 * present):
293 * <ul>
294 * <li>resultType</li>
295 * <li>maxFeatures</li>
296 * <li>startPosition</li>
297 * </ul>
298 *
299 * @param element
300 * @param useVersion_1_0_0 if the filterencoding 1.0.0 rules should be applied.
301 * @return corresponding <code>Query</code> instance
302 * @throws XMLParsingException
303 */
304 public static Query create( Element element, boolean useVersion_1_0_0 )
305 throws XMLParsingException {
306
307 GetFeatureDocument doc = new GetFeatureDocument();
308 Query query = doc.parseQuery( element, useVersion_1_0_0 );
309 return query;
310 }
311
312
313 /**
314 * Returns the handle attribute.
315 * <p>
316 * The handle attribute is included to allow a client to associate a mnemonic name to the query.
317 * The purpose of the handle attribute is to provide an error handling mechanism for locating a
318 * statement that might fail.
319 *
320 * @return the handle attribute
321 */
322 public String getHandle() {
323 return this.handle;
324 }
325
326 /**
327 * Returns the names of the requested feature types.
328 *
329 * @return the names of the requested feature types
330 */
331 public QualifiedName[] getTypeNames() {
332 return this.typeNames;
333 }
334
335 /**
336 * Returns the aliases for the requested feature types.
337 * <p>
338 * The returned array is either null or has the same length as the array returned by
339 * {@link #getTypeNames()}.
340 *
341 * @see #getTypeNames()
342 * @return the aliases for the requested feature types, or null if no aliases are used
343 */
344 public String[] getAliases() {
345 return this.aliases;
346 }
347
348 /**
349 * Returns the srsName attribute.
350 *
351 * @return the srsName attribute
352 */
353 public String getSrsName() {
354 return this.srsName;
355 }
356
357 /**
358 * Sets the srsName attribute to given value.
359 *
360 * @param srsName
361 * name of the requested SRS
362 */
363 public void setSrsName( String srsName ) {
364 this.srsName = srsName;
365 }
366
367 /**
368 * Returns the featureVersion attribute.
369 *
370 * The version attribute is included in order to accommodate systems that support feature
371 * versioning. A value of ALL indicates that all versions of a feature should be fetched.
372 * Otherwise an integer can be specified to return the n th version of a feature. The version
373 * numbers start at '1' which is the oldest version. If a version value larger than the largest
374 * version is specified then the latest version is return. The default action shall be for the
375 * query to return the latest version. Systems that do not support versioning can ignore the
376 * parameter and return the only version that they have.
377 *
378 * @return the featureVersion attribute
379 */
380 public String getFeatureVersion() {
381 return this.featureVersion;
382 }
383
384 /**
385 * Returns all requested properties.
386 *
387 * @return all requested properties
388 *
389 * @see #getFunctions()
390 */
391 public PropertyPath[] getPropertyNames() {
392 return this.propertyNames;
393 }
394
395 /**
396 * Beside property names a query may contains 0 to n functions modifying the values of one or
397 * more original properties. E.g. instead of area and population the density of a country can be
398 * requested by using a function instead:
399 *
400 * <pre>
401 * <ogc:Div>
402 * <ogc:PropertyName>population</ogc:PropertyName>
403 * <ogc:PropertyName>area</ogc:PropertyName>
404 * </ogc:Div>
405 * </pre>
406 *
407 * <p>
408 * If no functions and no property names are specified all properties should be fetched.
409 * </p>
410 *
411 * @return requested functions
412 *
413 * @see #getPropertyNames()
414 */
415 public Function[] getFunctions() {
416 return this.functions;
417 }
418
419 /**
420 * Returns the filter that limits the query.
421 *
422 * @return the filter that limits the query
423 */
424 public Filter getFilter() {
425 return this.filter;
426 }
427
428 /**
429 * Returns the sort criteria for the result.
430 *
431 * @return the sort criteria for the result
432 */
433 public SortProperty[] getSortProperties() {
434 return this.sortProperties;
435 }
436
437 /**
438 * Returns the value of the resultType attribute ("inherited" from the GetFeature container).
439 *
440 * @return the value of the resultType attribute
441 */
442 public RESULT_TYPE getResultType() {
443 return this.resultType;
444 }
445
446 /**
447 * Returns the value of the maxFeatures attribute ("inherited" from the GetFeature container).
448 *
449 * The optional maxFeatures attribute can be used to limit the number of features that a
450 * GetFeature request retrieves. Once the maxFeatures limit is reached, the result set is
451 * truncated at that point. If not limit is set -1 will be returned
452 *
453 * @return the value of the maxFeatures attribute
454 */
455 public int getMaxFeatures() {
456 return this.maxFeatures;
457 }
458
459 /**
460 * @param maxFeatures
461 */
462 public void setMaxFeatures( int maxFeatures ) {
463 this.maxFeatures = maxFeatures;
464 }
465
466 /**
467 * Returns the value of the startPosition attribute ("inherited" from the GetFeature container).
468 * <p>
469 * The startPosition parameter identifies the first result set entry to be returned. If no
470 * startPosition is set explicitly, 1 will be returned.
471 *
472 * @return the value of the startPosition attribute, 1 if undefined
473 */
474 public int getStartPosition() {
475 return this.startPosition;
476 }
477
478 /**
479 * @see #getStartPosition()
480 * @param startPosition
481 */
482 public void setStartPosition(int startPosition) {
483 this.startPosition = startPosition;
484 }
485
486 /**
487 * Returns a string representation of the object.
488 *
489 * @return a string representation of the object
490 */
491 @Override
492 public String toString() {
493 String ret = null;
494 ret = "propertyNames = " + propertyNames + "\n";
495 ret += ( "handle = " + handle + "\n" );
496 ret += ( "version = " + featureVersion + "\n" );
497 ret += ( "typeName = " + typeNames + "\n" );
498 ret += ( "filter = " + filter + "\n" );
499 return ret;
500 }
501 }