001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/csw/discovery/GetRecords.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2007 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 Aennchenstr. 19
030 53115 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.csw.discovery;
044
045 import java.io.StringReader;
046 import java.net.URI;
047 import java.net.URISyntaxException;
048 import java.util.Map;
049
050 import org.deegree.framework.log.ILogger;
051 import org.deegree.framework.log.LoggerFactory;
052 import org.deegree.framework.util.StringTools;
053 import org.deegree.framework.xml.XMLTools;
054 import org.deegree.i18n.Messages;
055 import org.deegree.model.filterencoding.AbstractFilter;
056 import org.deegree.model.filterencoding.Filter;
057 import org.deegree.ogcbase.ExceptionCode;
058 import org.deegree.ogcbase.SortProperty;
059 import org.deegree.ogcwebservices.InvalidParameterValueException;
060 import org.deegree.ogcwebservices.MissingParameterValueException;
061 import org.deegree.ogcwebservices.OGCWebServiceException;
062 import org.deegree.ogcwebservices.OperationNotSupportedException;
063 import org.deegree.ogcwebservices.csw.AbstractCSWRequest;
064 import org.w3c.dom.Document;
065 import org.w3c.dom.Element;
066
067 /**
068 * Class representation of a <code>GetRecords</code> request.
069 * <p>
070 * The primary means of resource discovery in the general model are the two operations search and
071 * present. In the HTTP protocol binding these are combined in the form of the mandatory
072 * <code>GetRecords</code> operation, which does a search.
073 * <p>
074 * Parameters specific to the <code>GetRecords</code> -request (omitting REQUEST, SERVICE and
075 * VERSION): <table border="1">
076 * <tr>
077 * <th>Name</th>
078 * <th>Occurences</th>
079 * <th>Function</th>
080 * </tr>
081 * <tr>
082 * <td align="center">NAMESPACE</td>
083 * <td align="center">0|1</td>
084 * <td>The NAMESPACE parameter is included in the KVP encoding to allow clients to bind any
085 * namespace prefixes that might be used for qualified names specified in other parameters. For
086 * example, the typeName parameter may include qualified names of the form namespace prefix:name.
087 * The value of the NAMESPACE parameter is a comma separated list of character strings of the form
088 * [namespace prefix:] namespace url. Not including the name namespace prefix binds the specified
089 * URL to the default namespace. As in XML, only one default namespace may be bound. This parameter
090 * is not required for the XML encoding since XML includes a mechanism for binding namespace
091 * prefixes.</td>
092 * </tr>
093 * <tr>
094 * <td align="center">resultType</td>
095 * <td align="center">0|1 (default: RESULTS)</td>
096 * <td>The resultType parameter may have the values HITS, RESULTS or VALIDATE and is used to
097 * indicate whether the catalogue service returns the full result set, the number of hits the query
098 * found or validates the request. If the resultType parameter is set to HITS, the catalogue service
099 * shall return an empty <GetRecordsResponse> element with the numberOfRecordsMatched
100 * attribute set to indicate the number of hits. The other attributes may be set to zero or not
101 * specified at all if they are optional. If the resultType parameter is set to HITS, then the
102 * values for the parameters outputFormat and outputSchema (if specified) shall be ignored since no
103 * actual records will be returned. If the resultType parameter is set to RESULTS, the catalogue
104 * service should generate a complete response with the <GetRecordsResponse> element
105 * containing the result set for the request. If the resultType parameter is set to VALIDATE, the
106 * catalogue service shall validate the request and return an empty <GetRecordsResponse>. All
107 * mandatory attributes may be given a value of zero and all optional attributes may be omitted. If
108 * the request does not validate then a service exception shall be raised as describe in Subclause
109 * 10.3.2.3.</td>
110 * </tr>
111 * <tr>
112 * <td align="center">outputFormat</td>
113 * <td align="center">0|1 (default: text/xml)</td>
114 * <td>The outputFormat parameter is used to control the format of the output that is generated in
115 * response to a GetRecords request. Its value must be a MIME type. The default value, "text/xml",
116 * means that the output shall be an XML document. All registries shall at least support XML as an
117 * output format. Other output formats may be supported and may include output formats such as TEXT
118 * (MIME type text/plain), or HTML (MIME type text/html). The list of output formats that a CSW
119 * instance provides must be advertised in the Capabilities document. In the case where the output
120 * format is text/xml, the CSW must generate an XML document that validates against a schema
121 * document that is specified in the output document via the xsi:schemaLocation attribute defined in
122 * XML.</td>
123 * </tr>
124 * <tr>
125 * <td align="center">outputSchema</td>
126 * <td align="center">0|1 (default: OGCCORE)</td>
127 * <td>The outputSchema parameter is used to indicate the schema of the output that is generated in
128 * response to a GetRecords request. The default value for this parameter shall be OGCCORE
129 * indicating that the schema for the core returnable properties (as defined in subclause 6.3.3)
130 * shall be used. Application profiles may define additional values for outputSchema and may
131 * redefine the default value but all profiles must support the value OGCCORE. Examples values for
132 * the outputSchema parameter might be FGDC, or ISO19119, ISO19139 or ANZLIC. The list of supported
133 * output schemas must be advertised in the capabilities document.</tr>
134 * <tr>
135 * <td align="center">startPosition</td>
136 * <td align="center">0|1 (default: 1)</td>
137 * <td>The startPosition paramater is used to indicate at which record position the catalogue
138 * should start generating output. The default value is 1 meaning it starts at the first record in
139 * the result set.</td>
140 * </tr>
141 * <tr>
142 * <td align="center">maxRecords</td>
143 * <td align="center">0|1 (default: 10)</td>
144 * <td>The maxRecords parameter is used to define the maximum number of records that should be
145 * returned from the result set of a query. If it is not specified, then 10 records shall be
146 * returned. If its value is set to zero, then the behavior is indentical to setting
147 * "resultType=HITS" as described above.</td>
148 * </tr>
149 * <tr>
150 * <td align="center">typeName</td>
151 * <td align="center">1</td>
152 * <td>The typeName parameter is a list of record type names that define a set of metadata record
153 * element names which will be constrained in the predicate of the query. In addition, all or some
154 * of the these names may be specified in the query to define which metadata record elements the
155 * query should present in the response to the GetRecords operation.</td>
156 * </tr>
157 * <tr>
158 * <td align="center">ElementSetName / ElementName</td>
159 * <td align="center">* (default: 10)</td>
160 * <td>The ElementName parameter is used to specify one or more metadata record elements that the
161 * query should present in the response to the a GetRecords operation. Well known sets of element
162 * may be named, in which case the ElementSetName parameter may be used (e.g.brief, summary or
163 * full). If neither parameter is specified, then a CSW shall present all metadata record elements.
164 * As mentioned above, if the outputFormat parameter is set to text/xml, then the response to the
165 * GetRecords operation shall validate against a schema document that is referenced in the response
166 * using the xmlns attributes. If the set of metadata record elements that the client specifies in
167 * the query in insufficient to generate a valid XML response document, a CSW may augment the list
168 * of elements presented to the client in order to be able to generate a valid document. Thus a
169 * client application should expect to receive more than the requested elements if the output format
170 * is set to XML. </td>
171 * </tr>
172 * <tr>
173 * <td align="center">CONSTRAINTLANGUAGE / Constraint</td>
174 * <td align="center">0|1</td>
175 * <td>Each request encoding (XML and KVP) has a specific mechanism for specifying the predicate
176 * language that will be used to constrain a query. In the XML encoding, the element
177 * <Constraint> is used to define the query predicate. The root element of the content of the
178 * <Constraint> element defines the predicate language that is being used. Two possible root
179 * elements are <ogc:Filter> for the OGC XML filter encoding, and <csw:CqlText> for a
180 * common query language string. An example predicate specification in the XML encoding is:
181 *
182 * <Constraint> <CqlText>prop1!=10</CqlText> </Constraint>
183 *
184 * In the KVP encoding, the parameter CONSTRAINTLANGUAGE is used to specify the predicate language
185 * being used. The Constraint parameter is used to specify the actual predicate. For example, to
186 * specify a CQL predicate, the following parameters would be set in the KVP encoding: <br>
187 *
188 * ...CONSTRAINTLANGUAGE=CQL_TEXT&CONSTRAINT="prop1!=10"...
189 *
190 * </td>
191 * </tr>
192 * <tr>
193 * <td align="center">SortBy</td>
194 * <td align="center">0|1</td>
195 * <td>The result set may be sorted by specifying one or more metadata record elements upon which
196 * to sort. In KVP encoding, the SORTBY parameter is used to specify the list of sort elements. The
197 * value for the SORTBY parameter is a comma-separated list of metadata record element names upon
198 * which to sort the result set. The format for each element in the list shall be either element
199 * name:A indicating that the element values should be sorted in ascending order or element name:D
200 * indicating that the element values should be sorted in descending order. For XML encoded
201 * requests, the <ogc:SortBy> element is used to specify a list of sort metadata record
202 * elements. The attribute sortOrder is used to specify the sort order for each element. Valid
203 * values for the sortOrder attribute are ASC indicating an ascending sort and DESC indicating a
204 * descending sort.</td>
205 * </tr>
206 * <tr>
207 * <td align="center">DistributedSearch / hopCount</td>
208 * <td align="center">0|1 (default: FALSE)</td>
209 * <td>The DistributedSearch parameter may be used to indicate that the query should be
210 * distributed. The default query behaviour, if the DistributedSearch parameter is set to FALSE (or
211 * is not specified at all), is to execute the query on the local server. In the XML encoding, if
212 * the <DistributedSearch> element is not specified then the query is executed on the local
213 * server. <br>
214 * <br>
215 * The hopCount parameter controls the distributed query behaviour by limiting the maximum number of
216 * message hops before the search is terminated. Each catalogue decrements this value by one when
217 * the request is received and does not propagate the request if the hopCount=0.</td>
218 * </tr>
219 * <tr>
220 * <td align="center">ResponseHandler</td>
221 * <td align="center">0|1</td>
222 * <td>The ResponseHandler parameter is a flag that indicates how the GetRecords operation should
223 * be processed by a CSW. If the parameter is not present, then the GetRecords operation is
224 * processed synchronously meaning that the client sends the GetRecords request to a CSW and waits
225 * to receive a valid response or exception message. The CSW immediately processes the GetRecords
226 * request while the client waits for a response. The problem with this mode of operation is that
227 * the client may timeout waiting for the CSW to process the request. If the ResponseHandler
228 * parameter is present, the GetRecords operation is processed asynchronously. In this case, the CSW
229 * responds immediately to a client's request with an acknowledgment message that tells the client
230 * that the request has been received and validated, and notification of completion will be sent to
231 * the URI specified as the value of the ResponseHandler parameter.</td>
232 * </tr>
233 * </table>
234 *
235 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
236 * @version $Revision: 7506 $
237 *
238 *
239 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
240 * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </a>
241 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
242 *
243 * @author last edited by: $Author: apoth $
244 *
245 * @version $Revision: 7506 $, $Date: 2007-06-06 18:09:41 +0200 (Mi, 06 Jun 2007) $
246 */
247
248 public class GetRecords extends AbstractCSWRequest {
249
250 private static final long serialVersionUID = 2796229558893029054L;
251
252 private static final ILogger LOG = LoggerFactory.getLogger( GetRecords.class );
253
254 protected static final String DEFAULT_OUTPUTFORMAT = "application/xml";
255
256 protected static final String DEFAULT_OUTPUTSCHEMA = "csw:Record";
257
258 protected static final int DEFAULT_STARTPOSITION = 1;
259
260 protected static final int DEFAULT_MAX_RECORDS = 10;
261
262 protected static final int DEFAULT_HOPCOUNT = 2;
263
264 protected static final String DEFAULT_VERSION = "2.0.0";
265
266 /**
267 * defining HITS as String
268 */
269 public static String RESULT_TYPE_STRING_HITS = "HITS";
270
271 /**
272 * defining VALIDATE as String
273 */
274 public static String RESULT_TYPE_STRING_VALIDATE = "VALIDATE";
275
276 /**
277 * defining RESULTS as String
278 */
279 public static String RESULT_TYPE_STRING_RESULTS = "RESULTS";
280
281 private RESULT_TYPE resultType = RESULT_TYPE.RESULTS;
282
283 // keys are Strings (namespace prefix or "" for default namespace), values
284 // are URIs
285 private Map<String, URI> namespace;
286
287 private String outputFormat;
288
289 private String outputSchema;
290
291 private int startPosition;
292
293 private int maxRecords;
294
295 private int hopCount;
296
297 private URI responseHandler;
298
299 //private Query[] queries;
300
301 private Query query;
302
303 /**
304 * Creates a new <code>GetRecords</code> instance.
305 *
306 * @param id
307 * @param version
308 * @param vendorSpecificParameters
309 * @param namespace
310 * @param resultType
311 * @param outputFormat
312 * @param outputSchema
313 * @param startPosition
314 * @param maxRecords
315 * @param hopCount
316 * @param responseHandler
317 * @param query
318 */
319 public GetRecords( String id, String version, Map<String, String> vendorSpecificParameters,
320 Map<String, URI> namespace, RESULT_TYPE resultType, String outputFormat,
321 String outputSchema, int startPosition, int maxRecords, int hopCount,
322 URI responseHandler, Query query ) {
323 super( version, id, vendorSpecificParameters );
324 this.namespace = namespace;
325 this.resultType = resultType;
326 this.outputFormat = outputFormat;
327 this.outputSchema = outputSchema;
328 this.startPosition = startPosition;
329 this.maxRecords = maxRecords;
330 this.hopCount = hopCount;
331 this.responseHandler = responseHandler;
332 this.query = query;
333 }
334
335 /**
336 * creates a GetRecords request from the XML fragment passed. The passed element must be valid
337 * against the OGC CSW 2.0 GetRecords schema.
338 *
339 * TODO respect namespaces (use QualifiedNames) for type names
340 *
341 * @param id
342 * unique ID of the request
343 * @param root
344 * root element of the GetRecors request
345 * @return a GetRecords instance with given id and parsed values from the root element
346 * @throws MissingParameterValueException
347 * if a required parameter was not set
348 * @throws InvalidParameterValueException
349 * if a parameter is invalid
350 * @throws OGCWebServiceException
351 * if something went wrong while creating the Request
352 */
353 public static GetRecords create( String id, Element root )
354 throws MissingParameterValueException, InvalidParameterValueException,
355 OGCWebServiceException {
356
357 GetRecordsDocument document = new GetRecordsDocument();
358 document.setRootElement( root );
359 GetRecords ogcRequest = document.parse( id );
360
361 return ogcRequest;
362 }
363
364 /**
365 * Creates a new <code>GetRecords</code> instance from the values stored in the submitted Map.
366 * Keys (parameter names) in the Map must be uppercase.
367 *
368 * @TODO evaluate vendorSpecificParameter
369 *
370 * @param kvp
371 * Map containing the parameters
372 * @return a GetRecords instance with given id and values from the kvp
373 * @exception InvalidParameterValueException
374 * @exception MissingParameterValueException
375 * @throws OperationNotSupportedException
376 * if an CQL_TEXT constrain is requested
377 */
378 public static GetRecords create( Map<String, String> kvp )
379 throws InvalidParameterValueException, MissingParameterValueException,
380 OperationNotSupportedException {
381
382
383 // String version = "2.0.0";
384 //Map<String, String> vendorSpecificParameters = null;
385 // RESULT_TYPE resultType = RESULT_TYPE.HITS;
386 // String outputFormat = "text/xml";
387 // String outputSchema = "OGCCORE";
388 // int startPosition = 1;
389 // int maxRecords = 10;
390 // int hopCount = 2;
391
392 String service = getParam( "SERVICE", kvp, "CSW" );
393 if ( !"CSW".equals( service ) ) {
394 throw new InvalidParameterValueException(
395 "GetRecordDocument",
396 Messages.getMessage( "CSW_INVALID_SERVICE_PARAM" ),
397 ExceptionCode.INVALIDPARAMETERVALUE );
398 }
399
400 String id = getParam( "ID", kvp, "" );
401 LOG.logDebug( "GetRecordRequest id=" + id );
402
403
404 String version = getParam( "VERSION", kvp, DEFAULT_VERSION );
405 if ( ! (DEFAULT_VERSION.equals( version ) ||
406 "2.0.1".equals( version ) ||
407 "2.0.2".equals( version ) ) ) {
408 throw new InvalidParameterValueException("GetRecords",
409 Messages.getMessage(
410 "CSW_NOT_SUPPORTED_VERSION",
411 GetRecords.DEFAULT_VERSION,
412 "2.0.1",
413 "2.0.2",
414 version ),
415 ExceptionCode.INVALIDPARAMETERVALUE ) ;
416 }
417
418 // extract namespace mappings
419 Map<String, URI> namespaceMappings = getNSMappings( getParam( "NAMESPACE", kvp, null ) );
420
421 String resultTypeString = getParam( "RESULTTYPE", kvp, RESULT_TYPE_STRING_HITS );
422 RESULT_TYPE resultType = RESULT_TYPE.HITS;
423 if ( RESULT_TYPE_STRING_HITS.equalsIgnoreCase( resultTypeString ) ) {
424 resultType = RESULT_TYPE.HITS;
425 } else if ( RESULT_TYPE_STRING_RESULTS.equalsIgnoreCase( resultTypeString ) ) {
426 resultType = RESULT_TYPE.RESULTS;
427 } else if ( RESULT_TYPE_STRING_VALIDATE.equalsIgnoreCase( resultTypeString ) ) {
428 resultType = RESULT_TYPE.VALIDATE;
429 } else {
430 throw new InvalidParameterValueException(
431 "GetRecords",
432 Messages.getMessage(
433 "CSW_INVALID_RESULTTYPE",
434 resultTypeString,
435 GetRecords.RESULT_TYPE_STRING_HITS,
436 GetRecords.RESULT_TYPE_STRING_RESULTS,
437 GetRecords.RESULT_TYPE_STRING_VALIDATE ),
438 ExceptionCode.INVALIDPARAMETERVALUE );
439 }
440
441 String outputFormat = getParam( "OUTPUTFORMAT", kvp, DEFAULT_OUTPUTFORMAT );
442 String outputSchema = getParam( "OUTPUTSCHEMA", kvp, DEFAULT_OUTPUTSCHEMA );
443 int startPosition = getParamAsInt( "STARTPOSITION", kvp, DEFAULT_STARTPOSITION );
444 if ( startPosition < 1 ) {
445 String msg = Messages.getMessage( "CSW_INVALID_STARTPOSITION",
446 new Integer( startPosition ) );
447 throw new InvalidParameterValueException( msg );
448 }
449 int maxRecords = getParamAsInt( "MAXRECORDS", kvp, DEFAULT_MAX_RECORDS );
450
451 if ( maxRecords < 0 ) {
452 maxRecords = DEFAULT_MAX_RECORDS;
453 }
454
455 // build one Query object for each specified typeName
456 String tmp = getRequiredParam( "TYPENAMES", kvp );
457 String[] typeNames = StringTools.toArray( tmp, ",", false );
458 if ( typeNames.length == 0 ) {
459 throw new MissingParameterValueException( "Mandatory parameter 'TYPENAMES' is missing!" );
460 }
461
462 String elementSetName = kvp.remove( "ELEMENTSETNAME" );
463 if ( elementSetName == null ) {
464 elementSetName = kvp.remove( "ELEMENTNAME" );
465 } else {
466 String test = kvp.remove( "ELEMENTNAME" );
467 if( test != null ){
468 LOG.logInfo( Messages.getMessage( "CSW_ELEMENT_SET_NAME_DUPLICATE") );
469 }
470 }
471 String[] elementNames = null;
472 if( elementSetName != null ){
473 elementNames = StringTools.toArray( elementSetName, ",", false );
474 if ( elementNames.length == 0 ) {
475 elementNames = null;
476 }
477 }
478 if ( elementNames == null ){
479 elementNames = new String[]{"Full"};
480 }
481
482 String constraintString = kvp.remove( "CONSTRAINT" );
483 Filter constraint = null;
484 String constraintLanguage = null;
485 if ( constraintString != null ) {
486 // build Filter object (from CONSTRAINT parameter)
487 constraintLanguage = kvp.remove( "CONSTRAINTLANGUAGE" );
488 if ( constraintLanguage != null ) {
489 if ( "CQL_TEXT".equalsIgnoreCase( constraintLanguage.trim() ) ) {
490 throw new OperationNotSupportedException(
491 Messages.getMessage( "CSW_NO_CQL_IMPLEMENTATION" ) );
492 } else if ( !"FILTER".equalsIgnoreCase( constraintLanguage.trim() ) ) {
493 throw new InvalidParameterValueException(
494 Messages.getMessage(
495 "CSW_INVALID_CONSTRAINT_LANGUAGE",
496 constraintLanguage.trim() ) );
497 }
498 } else {
499 throw new InvalidParameterValueException(
500 Messages.getMessage( "CSW_CQL_NOR_FILTER_KVP" ) );
501 }
502
503 try {
504 Document doc = XMLTools.parse( new StringReader( constraintString ) );
505 Element element = doc.getDocumentElement();
506 constraint = AbstractFilter.buildFromDOM( element );
507 } catch ( Exception e ) {
508 String msg = "An error occured when parsing the 'CONSTRAINT' parameter "
509 + "Filter expression: " + e.getMessage();
510 throw new InvalidParameterValueException( msg );
511 }
512 }
513
514
515 SortProperty[] sortProperties = SortProperty.create( kvp.remove( "SORTBY" ) );
516
517 // Query[] queries = new Query[typeNames.length];
518 // for ( int i = 0; i < typeNames.length; i++ ) {
519 Query query = new Query( elementSetName, elementNames, constraint, sortProperties,
520 typeNames );
521 // }
522
523 // find out if the query should be performed locally or in a distributed
524 // fashion
525 int hopCount = DEFAULT_HOPCOUNT;
526 String distributedSearch = getParam( "DISTRIBUTEDSEARCH", kvp, "false" );
527 if ( distributedSearch.equalsIgnoreCase( "true" ) ) {
528 hopCount = getParamAsInt( "HOPCOUNT", kvp, DEFAULT_HOPCOUNT );
529 }
530
531 String rHandler = kvp.remove( "RESPONSEHANDLER" );
532 URI responseHandler = null;
533 if ( rHandler != null ) {
534 try {
535 responseHandler = new URI( rHandler );
536 } catch ( URISyntaxException e ) {
537 throw new InvalidParameterValueException(
538 Messages.getMessage(
539 "CSW_INVALID_RESPONSE_HANDLER",
540 rHandler ) );
541 }
542 throw new OperationNotSupportedException(
543 Messages.getMessage( "CSW_NO_REPONSE_HANDLER_IMPLEMENTATION" ) );
544
545 }
546
547 return new GetRecords( id, version, kvp, namespaceMappings,
548 resultType, outputFormat, outputSchema, startPosition, maxRecords,
549 hopCount, responseHandler, query );
550 }
551
552 /**
553 * Used to specify a namespace and its prefix. Format must be [ <prefix>:] <url>. If the prefix
554 * is not specified then this is the default namespace
555 * <p>
556 * Zero or one (Optional) ; Include value for each distinct namespace used by all qualified
557 * names in the request. If not included, all qualified names are in default namespace
558 * <p>
559 * The NAMESPACE parameter is included in the KVP encoding to allow clients to bind any
560 * namespace prefixes that might be used for qualified names specified in other parameters. For
561 * example, the typeName parameter may include qualified names of the form namespace
562 * prefix:name.
563 * <p>
564 * The value of the NAMESPACE parameter is separated list of character strings of the form
565 * [namespace prefix:]namespace url. Not including the name namespace prefix binds the specified
566 * URL to the default namespace. As in XML, only one default namespace may be bound.
567 *
568 * @return the mapped namespaces or <code>null</code> if all qualified names are in default
569 * namespace.
570 *
571 */
572 public Map<String, URI> getNamespace() {
573 return this.namespace;
574 }
575
576 /**
577 * The resultType parameter may have the values HITS, RESULTS or VALIDATE and is used to
578 * indicate whether the catalogue service returns the full result set, the number of hits the
579 * query found or validates the request.
580 * <p>
581 * If the resultType parameter is set to HITS, the catalogue service shall return an empty
582 * <GetRecordsResponse>element with the numberOfRecordsMatched attribute set to indicate
583 * the number of hits. The other attributes may be set to zero or not specified at all if they
584 * are optional.
585 * <p>
586 * If the resultType parameter is set to HITS, then the values for the parameters outputFormat
587 * and outputSchema (if specified) shall be ignored since no actual records will be returned
588 * <p>
589 * If the resultType parameter is set to RESULTS, the catalogue service should generate a
590 * complete response with the <GetRecordsResponse>element containing the result set for
591 * the request
592 * <p>
593 * If the resultType parameter is set to VALIDATE, the catalogue service shall validate the
594 * request and return an empty <GetRecordsResponse>. All mandatory attributes may be given
595 * a value of zero and all optional attributes may be omitted. If the request does not validate
596 * then a service exception shall be raised
597 *
598 * @return one of HITS, RESULTS or VALIDATE
599 *
600 */
601 public RESULT_TYPE getResultType() {
602 return this.resultType;
603 }
604
605 /**
606 * The resultType parameter may have the values HITS, RESULTS or VALIDATE and is used to
607 * indicate whether the catalogue service returns the full result set, the number of hits the
608 * query found or validates the request.
609 * <p>
610 * If the resultType parameter is set to HITS, the catalogue service shall return an empty
611 * <GetRecordsResponse>element with the numberOfRecordsMatched attribute set to indicate
612 * the number of hits. The other attributes may be set to zero or not specified at all if they
613 * are optional.
614 * <p>
615 * If the resultType parameter is set to HITS, then the values for the parameters outputFormat
616 * and outputSchema (if specified) shall be ignored since no actual records will be returned
617 * <p>
618 * If the resultType parameter is set to RESULTS, the catalogue service should generate a
619 * complete response with the <GetRecordsResponse>element containing the result set for
620 * the request
621 * <p>
622 * If the resultType parameter is set to VALIDATE, the catalogue service shall validate the
623 * request and return an empty <GetRecordsResponse>. All mandatory attributes may be given
624 * a value of zero and all optional attributes may be omitted. If the request does not validate
625 * then a service exception shall be raised
626 *
627 * @return the resulttype as a String, one of "HITS", "VALIDATE" or "RESULTS"
628 *
629 */
630 public String getResultTypeAsString() {
631 String resultTypeString = null;
632 switch ( this.resultType ) {
633 case HITS: {
634 resultTypeString = RESULT_TYPE_STRING_HITS;
635 break;
636 }
637 case RESULTS: {
638 resultTypeString = RESULT_TYPE_STRING_RESULTS;
639 break;
640 }
641 case VALIDATE: {
642 resultTypeString = RESULT_TYPE_STRING_VALIDATE;
643 break;
644 }
645 }
646 return resultTypeString;
647 }
648
649 /**
650 * sets the resultType of a request. This may be useful to perform a request first with
651 * resultType = HITS to determine the total number of records matching a query and afterwards
652 * performing the same request with resultType = RESULTS (and maxRecords < number of matched
653 * records).
654 *
655 * @param resultType
656 */
657 public void setResultType( RESULT_TYPE resultType ) {
658 this.resultType = resultType;
659 }
660
661 /**
662 * returns <= 0 if no distributed search shall be performed. otherwise the recursion depht is
663 * returned.
664 * <p>
665 * The hopCount parameter controls the distributed query behaviour by limiting the maximum
666 * number of message hops before the search is terminated. Each catalogue decrements this value
667 * by one when the request is received and does not propagate the request if the hopCount=0
668 *
669 * @return <= 0 if no distributed search shall be performed. otherwise the recursion depht is
670 * returned.
671 *
672 */
673 public int getHopCount() {
674 return this.hopCount;
675 }
676
677 /**
678 * Value is Mime type;The only value that must be supported is text/xml. Other suppored values
679 * may include text/html and text/plain
680 * <p>
681 * The outputFormat parameter is used to control the format of the output that is generated in
682 * response to a GetRecords request. Its value must be a MIME type. The default value,
683 * "text/xml", means that the output shall be an XML document. All registries shall at least
684 * support XML as an output format. Other output formats may be supported and may include output
685 * formats such as TEXT (MIME type text/plain), or HTML (MIME type text/html). The list of
686 * output formats that a CSW instance provides must be advertised in the Capabilities document
687 * <p>
688 * In the case where the output format is text/xml, the CSW must generate an XML document that
689 * validates against a schema document that is specified in the output document via the
690 * xsi:schemaLocation attribute defined in XML
691 *
692 * @return Value is a Mime type
693 *
694 */
695 public String getOutputFormat() {
696 return this.outputFormat;
697 }
698
699 /**
700 * The outputSchema parameter is used to indicate the schema of the output that is generated in
701 * response to a GetRecords request. The default value for this parameter shall be OGCCORE
702 * indicating that the schema for the core returnable properties shall be used. Application
703 * profiles may define additional values for outputSchema and may redefine the default value but
704 * all profiles must support the value OGCCORE
705 * <p>
706 * Examples values for the outputSchema parameter might be FGDC, or ISO19119, ISO19139 or
707 * ANZLIC. The list of supported output schemas must be advertised in the capabilities document
708 *
709 * @return The default value for this parameter shall be OGCCORE
710 *
711 */
712 public String getOutputSchema() {
713 return this.outputSchema;
714 }
715
716 /**
717 * @return the number of the first returned dataset. Zero or one (Optional)Default value is 1.
718 * If startPosition > the number of datasets satisfying the constraint, no dataset will
719 * be returned
720 *
721 */
722 public int getStartPosition() {
723 return this.startPosition;
724 }
725
726 /**
727 * @return The maxRecords parameter. It is used to define the maximum number of records that
728 * should be returned from the result set of a query. If it is not specified, then 10
729 * records shall be returned. If its value is set to zero, then the behavior is
730 * indentical to setting "resultType=HITS"
731 *
732 */
733 public int getMaxRecords() {
734 return this.maxRecords;
735 }
736
737 /**
738 * @return an Array of Strings containing only one single uri.toString() with the location of
739 * the responsehandler.
740 * @deprecated the spec only defines one reponsehandler, the preferred way to get the
741 * ResponseHandler is the {@link #getResponseHandler()} method.
742 */
743 @Deprecated
744 public String[] getResponseHandlers() {
745 if ( responseHandler != null ) {
746 return new String[] { responseHandler.toString() };
747 }
748 return new String[0];
749 }
750
751 /**
752 * @return the location of a response adress to which an asynchronous result may be sent.
753 */
754 public URI getResponseHandler() {
755 return responseHandler;
756 }
757
758 /**
759 * @return returns an Array respresentation of the single query object.
760 * @deprecated this method is solely for backward compatibility please use the {@link #getQuery()} method instead.
761 */
762 @Deprecated
763 public Query[] getQueries() {
764 return new Query[]{query};
765 }
766
767 /**
768 * @return the query object.
769 */
770 public Query getQuery() {
771 return query;
772 }
773
774 /**
775 * @see #getQuery()
776 * @param query
777 */
778 public void setQuery(Query query) {
779 this.query = query;
780 }
781
782 /**
783 * The <code>RESULT_TYPE</code> a simple enum which defines some result values of a GetRecord.
784 *
785 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
786 *
787 * @author last edited by: $Author: apoth $
788 *
789 * @version $Revision: 7506 $, $Date: 2007-06-06 18:09:41 +0200 (Mi, 06 Jun 2007) $
790 *
791 */
792
793 public static enum RESULT_TYPE {
794 /**
795 * HITS, the catalogue service shall return an empty <GetRecordsResponse>element with
796 * the numberOfRecordsMatched attribute set to indicate the number of hits
797 */
798 HITS,
799 /**
800 * VALIDATE, the catalogue service shall validate the request
801 */
802 VALIDATE,
803 /**
804 * RESULTS, the catalogue service should generate a complete response with the
805 * <GetRecordsResponse>element containing the result set for the request
806 */
807 RESULTS
808 }
809 }