001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/csw/discovery/XMLFactory.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.csw.discovery;
037
038 import static org.deegree.ogcbase.CommonNamespaces.CSW202NS;
039 import static org.deegree.ogcbase.CommonNamespaces.CSWNS;
040
041 import java.net.URI;
042 import java.net.URISyntaxException;
043 import java.util.Date;
044 import java.util.HashMap;
045 import java.util.List;
046 import java.util.Map;
047 import java.util.Set;
048
049 import org.deegree.datatypes.QualifiedName;
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.util.TimeTools;
054 import org.deegree.framework.xml.XMLException;
055 import org.deegree.framework.xml.XMLTools;
056 import org.deegree.ogcbase.CommonNamespaces;
057 import org.deegree.ogcbase.PropertyPath;
058 import org.deegree.ogcbase.SortProperty;
059 import org.deegree.ogcwebservices.InvalidParameterValueException;
060 import org.deegree.ogcwebservices.OGCWebServiceException;
061 import org.deegree.ogcwebservices.csw.CSWExceptionCode;
062 import org.deegree.ogcwebservices.csw.CSWPropertiesAccess;
063 import org.w3c.dom.Attr;
064 import org.w3c.dom.Document;
065 import org.w3c.dom.Element;
066 import org.w3c.dom.NamedNodeMap;
067 import org.w3c.dom.Node;
068 import org.w3c.dom.NodeList;
069
070 /**
071 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
072 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
073 * @author last edited by: $Author: apoth $
074 *
075 * @version $Revision: 27404 $, $Date: 2010-10-19 17:45:39 +0200 (Di, 19 Okt 2010) $
076 */
077 public class XMLFactory extends org.deegree.ogcbase.XMLFactory {
078
079 private static final ILogger LOG = LoggerFactory.getLogger( XMLFactory.class );
080
081 /**
082 * Exports a <code>GetRecordsResponse</code> instance to a <code>GetRecordsResponseDocument</code>.
083 *
084 * @param response
085 * @return DOM representation of the <code>GetRecordsResponse</code>
086 * @throws XMLException
087 * if XML template could not be loaded
088 */
089 public static GetRecordsResultDocument export( GetRecordsResult response )
090 throws XMLException {
091 // 'version'-attribute
092 String version = response.getRequest().getVersion();
093 if ( version == null || "".equals( version.trim() ) ) {
094 version = "2.0.0";
095 }
096
097 GetRecordsResultDocument responseDocument = new GetRecordsResultDocument( version );
098
099 try {
100 Element rootElement = responseDocument.getRootElement();
101 Document doc = rootElement.getOwnerDocument();
102
103 // set required namespaces
104 Element recordRespRoot = response.getSearchResults().getRecords().getOwnerDocument().getDocumentElement();
105 NamedNodeMap nnm = recordRespRoot.getAttributes();
106 for ( int i = 0; i < nnm.getLength(); i++ ) {
107 Node node = nnm.item( i );
108 if ( node instanceof Attr ) {
109 rootElement.setAttribute( node.getNodeName(), node.getNodeValue() );
110 }
111 }
112
113 rootElement.setAttribute( "version", version );
114 String namespace = ( version.equals( "2.0.2" ) ? CSW202NS.toString() : CSWNS.toString() );
115
116 // 'RequestId'-element (optional)
117 if ( response.getRequest().getId() != null ) {
118 Element requestIdElement = doc.createElementNS( namespace, "csw:RequestId" );
119 requestIdElement.appendChild( doc.createTextNode( response.getRequest().getId() ) );
120 rootElement.appendChild( requestIdElement );
121 }
122
123 // 'SearchStatus'-element (required)
124 Element searchStatusElement = doc.createElementNS( namespace, "csw:SearchStatus" );
125 // 'status'-attribute (required)
126 if ( !version.equals( "2.0.2" ) ) {
127 searchStatusElement.setAttribute( "status", response.getSearchStatus().getStatus() );
128 }
129 // 'timestamp'-attribute (optional)
130 if ( response.getSearchStatus().getTimestamp() != null ) {
131 Date date = response.getSearchStatus().getTimestamp();
132 String time = TimeTools.getISOFormattedTime( date );
133 searchStatusElement.setAttribute( "timestamp", time );
134 }
135 rootElement.appendChild( searchStatusElement );
136
137 // 'SeachResults'-element (required)
138 Element searchResultsElement = doc.createElementNS( namespace, "csw:SearchResults" );
139 SearchResults results = response.getSearchResults();
140
141 // 'resultSetId'-attribute (optional)
142 if ( results.getResultSetId() != null ) {
143 searchResultsElement.setAttribute( "resultSetId", results.getResultSetId().toString() );
144 }
145 // 'elementSet'-attribute (optional)
146 if ( results.getElementSet() != null ) {
147 searchResultsElement.setAttribute( "elementSet", results.getElementSet().toString() );
148 }
149 // 'recordSchema'-attribute (optional)
150 if ( results.getRecordSchema() != null ) {
151 searchResultsElement.setAttribute( "recordSchema", results.getRecordSchema().toString() );
152 }
153 // 'numberOfRecordsMatched'-attribute (required)
154 searchResultsElement.setAttribute( "numberOfRecordsMatched", "" + results.getNumberOfRecordsMatched() );
155 // 'numberOfRecordsReturned'-attribute (required)
156 searchResultsElement.setAttribute( "numberOfRecordsReturned", "" + results.getNumberOfRecordsReturned() );
157 // 'nextRecord'-attribute (required)
158 searchResultsElement.setAttribute( "nextRecord", "" + results.getNextRecord() );
159 // 'expires'-attribute (optional)
160 if ( results.getExpires() != null ) {
161 Date date = results.getExpires();
162 String time = TimeTools.getISOFormattedTime( date );
163 searchResultsElement.setAttribute( "expires", time );
164 }
165 // append all children of the records container node
166 NodeList nl = results.getRecords().getChildNodes();
167 for ( int i = 0; i < nl.getLength(); i++ ) {
168 Node copy = doc.importNode( nl.item( i ), true );
169 searchResultsElement.appendChild( copy );
170 }
171 rootElement.appendChild( searchResultsElement );
172 } catch ( Exception e ) {
173 LOG.logError( e.getMessage(), e );
174 throw new XMLException( e.getMessage() );
175 }
176 return responseDocument;
177 }
178
179 /**
180 * Exports a instance of {@link GetRecordByIdResult} to a {@link GetRecordByIdResultDocument}.
181 *
182 * @param response
183 * @return a new document
184 * @throws XMLException
185 */
186 public static GetRecordByIdResultDocument export( GetRecordByIdResult response )
187 throws XMLException {
188
189 GetRecordByIdResultDocument doc = new GetRecordByIdResultDocument();
190
191 try {
192 doc.createEmptyDocument( response.getRequest().getVersion() );
193 Document owner = doc.getRootElement().getOwnerDocument();
194 if ( response != null && response.getRecords() != null ) {
195 for ( Node record : response.getRecords() ) {
196 Node copy = owner.importNode( record, true );
197 doc.getRootElement().appendChild( copy );
198 }
199 } else if ( "2.0.2".equals( response.getRequest().getVersion() )
200 && ( response == null || response.getRecord() == null ) ) {
201 throw new OGCWebServiceException( "A record with the given ID does nor exist in the CSW",
202 CSWExceptionCode.INVALIDPARAMETERVALUE );
203 }
204 } catch ( Exception e ) {
205 LOG.logError( e.getMessage(), e );
206 throw new XMLException( e.getMessage() );
207 }
208
209 return doc;
210 }
211
212 /**
213 * Exports a <code>DescribeRecordResponse</code> instance to a <code>DescribeRecordResponseDocument</code>.
214 *
215 * @param response
216 * @return DOM representation of the <code>DescribeRecordResponse</code>
217 * @throws XMLException
218 * if XML template could not be loaded
219 */
220 public static DescribeRecordResultDocument export( DescribeRecordResult response )
221 throws XMLException {
222
223 DescribeRecordResultDocument responseDocument = new DescribeRecordResultDocument();
224
225 String ns = response.getRequest().getVersion().equals( "2.0.2" ) ? CSW202NS.toString() : CSWNS.toString();
226
227 try {
228 responseDocument.createEmptyDocument( response.getRequest().getVersion() );
229 Element rootElement = responseDocument.getRootElement();
230 Document doc = rootElement.getOwnerDocument();
231
232 // 'SchemaComponent'-elements (required)
233 SchemaComponent[] components = response.getSchemaComponents();
234 for ( int i = 0; i < components.length; i++ ) {
235 Element schemaComponentElement = doc.createElementNS( ns, "csw:SchemaComponent" );
236
237 // 'targetNamespace'-attribute (required)
238 schemaComponentElement.setAttribute( "targetNamespace", components[i].getTargetNamespace().toString() );
239
240 // 'parentSchema'-attribute (optional)
241 if ( components[i].getParentSchema() != null ) {
242 schemaComponentElement.setAttribute( "parentSchema", components[i].getParentSchema().toString() );
243 }
244
245 // 'schemaLanguage'-attribute (required)
246 schemaComponentElement.setAttribute( "schemaLanguage", components[i].getSchemaLanguage().toString() );
247
248 XMLTools.insertNodeInto( components[i].getSchema().getRootElement(), schemaComponentElement );
249 rootElement.appendChild( schemaComponentElement );
250 }
251 } catch ( Exception e ) {
252 LOG.logError( e.getMessage(), e );
253 throw new XMLException( e.getMessage() );
254 }
255 return responseDocument;
256 }
257
258 /**
259 * Exports a <code>GetRecords</code> instance to a <code>GetRecordsDocument</code>.
260 *
261 * @param request
262 * @return DOM representation of the <code>GetRecords</code>
263 * @throws XMLException
264 * if some elements could not be appended
265 * @throws OGCWebServiceException
266 * if an error occurred while creating the xml-representation of the GetRecords bean.
267 */
268 public static GetRecordsDocument exportWithVersion( GetRecords request )
269 throws XMLException, OGCWebServiceException {
270
271 GetRecordsDocument getRecordsDocument = null;
272
273 // read class for version depenging parsing of GetRecords request from properties
274 String className = CSWPropertiesAccess.getString( "GetRecords" + request.getVersion() );
275 Class<?> clzz = null;
276 try {
277 clzz = Class.forName( className );
278 } catch ( ClassNotFoundException e ) {
279 LOG.logError( e.getMessage(), e );
280 throw new InvalidParameterValueException( e.getMessage(), e );
281 }
282 try {
283 getRecordsDocument = (GetRecordsDocument) clzz.newInstance();
284 } catch ( InstantiationException e ) {
285 LOG.logError( e.getMessage(), e );
286 throw new InvalidParameterValueException( e.getMessage(), e );
287 } catch ( IllegalAccessException e ) {
288 LOG.logError( e.getMessage(), e );
289 throw new InvalidParameterValueException( e.getMessage(), e );
290 }
291
292 // getRecordsDocument = new GetRecordsDocument();
293 try {
294 getRecordsDocument.createEmptyDocument();
295 } catch ( Exception e ) {
296 throw new XMLException( e.getMessage() );
297 }
298 Element rootElement = getRecordsDocument.getRootElement();
299 Document doc = rootElement.getOwnerDocument();
300
301 // 'version'-attribute
302 rootElement.setAttribute( "version", request.getVersion() );
303
304 // 'version'-attribute
305 rootElement.setAttribute( "service", "CSW" );
306
307 // 'resultType'-attribute
308 rootElement.setAttribute( "resultType", request.getResultTypeAsString() );
309
310 // 'outputFormat'-attribute
311 rootElement.setAttribute( "outputFormat", request.getOutputFormat() );
312
313 // 'outputSchema'-attribute
314 rootElement.setAttribute( "outputSchema", request.getOutputSchema() );
315
316 // 'startPosition'-attribute
317 rootElement.setAttribute( "startPosition", "" + request.getStartPosition() );
318
319 // 'maxRecords'-attribute
320 rootElement.setAttribute( "maxRecords", "" + request.getMaxRecords() );
321
322 URI localCSWNS = CSWNS;
323 if ( request.getVersion().equals( "2.0.2" ) ) {
324 localCSWNS = CSW202NS;
325 }
326
327 // '<csw:DistributedSearch>'-element
328 if ( request.getHopCount() != -1 ) {
329 Element distributedSearchElement = doc.createElementNS( localCSWNS.toString(), "csw:DistributedSearch" );
330
331 // 'hopCount'-attribute
332 distributedSearchElement.setAttribute( "hopCount", "" + request.getHopCount() );
333 rootElement.appendChild( distributedSearchElement );
334 }
335
336 // '<csw:ResponseHandler>'-elements (optional)
337 URI responseHandler = request.getResponseHandler();
338 if ( responseHandler != null ) {
339 Element responseHandlerElement = doc.createElementNS( localCSWNS.toString(), "csw:ResponseHandler" );
340 responseHandlerElement.appendChild( doc.createTextNode( responseHandler.toASCIIString() ) );
341 rootElement.appendChild( responseHandlerElement );
342
343 }
344
345 // '<csw:Query>'-elements (required)
346 Query query = request.getQuery();
347 if ( query != null ) {
348 LOG.logDebug( "Adding the csw:Query element to the csw:GetRecords document" );
349 Element queryElement = doc.createElementNS( localCSWNS.toString(), "csw:Query" );
350
351 // 'typeName'-attribute
352 // Testing for the list of typenames.
353 List<QualifiedName> typeNames = query.getTypeNamesAsList();
354 Map<String, QualifiedName> aliases = new HashMap<String, QualifiedName>(
355 query.getDeclaredTypeNameVariables() );
356 if ( typeNames.size() > 0 ) {
357 appendTypeNamesAttribute( rootElement, queryElement, typeNames, aliases );
358 } else {
359 String s = StringTools.listToString( query.getTypeNamesAsList(), ',' );
360 queryElement.setAttribute( "typeNames", s );
361 }
362
363 // '<csw:ElementSetName>'-element (optional)
364 if ( query.getElementSetName() != null ) {
365 Element elementSetNameElement = doc.createElementNS( localCSWNS.toString(), "csw:ElementSetName" );
366 List<QualifiedName> elementSetNameTypeNamesList = query.getElementSetNameTypeNamesList();
367 if ( query.getElementSetNameVariables() != null && query.getElementSetNameVariables().size() > 0 ) {
368 throw new OGCWebServiceException(
369 "The elementSetName element in a csw:GetRecords request may not refrerence variables (aka. aliases), aborting request" );
370 }
371 if ( elementSetNameTypeNamesList.size() > 0 ) {
372 appendTypeNamesAttribute( rootElement, elementSetNameElement, elementSetNameTypeNamesList, null );
373 }
374 elementSetNameElement.appendChild( doc.createTextNode( query.getElementSetName() ) );
375 queryElement.appendChild( elementSetNameElement );
376 }
377
378 // '<csw:ElementName>'-elements (optional)
379 if ( query.getElementNamesAsPropertyPaths() != null ) {
380 List<PropertyPath> elementNames = query.getElementNamesAsPropertyPaths();
381 for ( int j = 0; j < elementNames.size(); j++ ) {
382 Element elementNameElement = doc.createElementNS( localCSWNS.toString(), "csw:ElementName" );
383 elementNameElement.appendChild( doc.createTextNode( elementNames.get( j ).getAsString() ) );
384 queryElement.appendChild( elementNameElement );
385 }
386 }
387
388 // '<csw:Constraint>'-element (optional)
389 if ( query.getContraint() != null ) {
390 Element constraintElement = doc.createElementNS( localCSWNS.toString(), "csw:Constraint" );
391 constraintElement.setAttribute( "version", "1.1.0" );
392 org.deegree.model.filterencoding.XMLFactory.appendFilter( constraintElement, query.getContraint() );
393 queryElement.appendChild( constraintElement );
394 }
395
396 // '<ogc:SortBy>'-element (optional)
397 SortProperty[] sortProperties = query.getSortProperties();
398 if ( sortProperties != null && sortProperties.length != 0 ) {
399 Element sortByElement = doc.createElementNS( OGCNS.toString(), "ogc:SortBy" );
400
401 // '<ogc:SortProperty>'-elements
402 for ( int j = 0; j < sortProperties.length; j++ ) {
403 Element sortPropertiesElement = doc.createElementNS( OGCNS.toString(), "ogc:SortProperty" );
404
405 // '<ogc:PropertyName>'-element (required)
406 Element propertyNameElement = doc.createElementNS( OGCNS.toString(), "ogc:PropertyName" );
407 appendPropertyPath( propertyNameElement, sortProperties[j].getSortProperty() );
408
409 // '<ogc:SortOrder>'-element (optional)
410 Element sortOrderElement = doc.createElementNS( OGCNS.toString(), "ogc:SortOrder" );
411 Node tn = doc.createTextNode( sortProperties[j].getSortOrder() ? "ASC" : "DESC" );
412 sortOrderElement.appendChild( tn );
413
414 sortPropertiesElement.appendChild( propertyNameElement );
415 sortPropertiesElement.appendChild( sortOrderElement );
416 sortByElement.appendChild( sortPropertiesElement );
417 }
418 queryElement.appendChild( sortByElement );
419 }
420 rootElement.appendChild( queryElement );
421 }
422 return getRecordsDocument;
423 }
424
425 /**
426 * Exports a <code>GetRecords</code> instance to a <code>GetRecordsDocument</code>.
427 *
428 * @param request
429 * @return DOM representation of the <code>GetRecords</code>
430 * @throws XMLException
431 * if some elements could not be appended
432 * @throws OGCWebServiceException
433 * if an error occurred while creating the xml-representation of the GetRecords bean.
434 */
435 public static GetRecordsDocument export( GetRecords request )
436 throws XMLException, OGCWebServiceException {
437
438 GetRecordsDocument getRecordsDocument = null;
439
440 getRecordsDocument = new GetRecordsDocument();
441 try {
442 getRecordsDocument.createEmptyDocument();
443 } catch ( Exception e ) {
444 throw new XMLException( e.getMessage() );
445 }
446 Element rootElement = getRecordsDocument.getRootElement();
447 Document doc = rootElement.getOwnerDocument();
448
449 // 'version'-attribute
450 rootElement.setAttribute( "version", request.getVersion() );
451
452 // 'resultType'-attribute
453 rootElement.setAttribute( "resultType", request.getResultTypeAsString() );
454
455 // 'outputFormat'-attribute
456 rootElement.setAttribute( "outputFormat", request.getOutputFormat() );
457
458 // 'outputSchema'-attribute
459 rootElement.setAttribute( "outputSchema", request.getOutputSchema() );
460
461 // 'startPosition'-attribute
462 rootElement.setAttribute( "startPosition", "" + request.getStartPosition() );
463
464 // 'maxRecords'-attribute
465 rootElement.setAttribute( "maxRecords", "" + request.getMaxRecords() );
466
467 // '<csw:DistributedSearch>'-element
468 if ( request.getHopCount() != -1 ) {
469 Element distributedSearchElement = doc.createElementNS( CSWNS.toString(), "csw:DistributedSearch" );
470
471 // 'hopCount'-attribute
472 distributedSearchElement.setAttribute( "hopCount", "" + request.getHopCount() );
473 rootElement.appendChild( distributedSearchElement );
474 }
475
476 // '<csw:ResponseHandler>'-elements (optional)
477 URI responseHandler = request.getResponseHandler();
478 if ( responseHandler != null ) {
479 Element responseHandlerElement = doc.createElementNS( CSWNS.toString(), "csw:ResponseHandler" );
480 responseHandlerElement.appendChild( doc.createTextNode( responseHandler.toASCIIString() ) );
481 rootElement.appendChild( responseHandlerElement );
482
483 }
484
485 // '<csw:Query>'-elements (required)
486 Query query = request.getQuery();
487 if ( query != null ) {
488 LOG.logDebug( "Adding the csw:Query element to the csw:GetRecords document" );
489 Element queryElement = doc.createElementNS( CSWNS.toString(), "csw:Query" );
490
491 // 'typeName'-attribute
492 // Testing for the list of typenames.
493 List<QualifiedName> typeNames = query.getTypeNamesAsList();
494 Map<String, QualifiedName> aliases = new HashMap<String, QualifiedName>(
495 query.getDeclaredTypeNameVariables() );
496 if ( typeNames.size() > 0 ) {
497 appendTypeNamesAttribute( rootElement, queryElement, typeNames, aliases );
498 } else {
499
500 String s = StringTools.arrayToString( query.getTypeNames(), ',' );
501 queryElement.setAttribute( "typeNames", s );
502 }
503
504 // '<csw:ElementSetName>'-element (optional)
505 if ( query.getElementSetName() != null ) {
506 Element elementSetNameElement = doc.createElementNS( CSWNS.toString(), "csw:ElementSetName" );
507 List<QualifiedName> elementSetNameTypeNamesList = query.getElementSetNameTypeNamesList();
508 if ( query.getElementSetNameVariables() != null && query.getElementSetNameVariables().size() > 0 ) {
509 throw new OGCWebServiceException(
510 "The elementSetName element in a csw:GetRecords request may not refrerence variables (aka. aliases), aborting request" );
511 }
512 if ( elementSetNameTypeNamesList.size() > 0 ) {
513 appendTypeNamesAttribute( rootElement, elementSetNameElement, elementSetNameTypeNamesList, null );
514 }
515 elementSetNameElement.appendChild( doc.createTextNode( query.getElementSetName() ) );
516 queryElement.appendChild( elementSetNameElement );
517 }
518
519 // '<csw:ElementName>'-elements (optional)
520 if ( query.getElementNamesAsPropertyPaths() != null ) {
521 List<PropertyPath> elementNames = query.getElementNamesAsPropertyPaths();
522 for ( int j = 0; j < elementNames.size(); j++ ) {
523 Element elementNameElement = doc.createElementNS( CSWNS.toString(), "csw:ElementName" );
524 elementNameElement.appendChild( doc.createTextNode( elementNames.get( j ).getAsString() ) );
525 queryElement.appendChild( elementNameElement );
526 }
527 }
528
529 // '<csw:Constraint>'-element (optional)
530 if ( query.getContraint() != null ) {
531 Element constraintElement = doc.createElementNS( CSWNS.toString(), "csw:Constraint" );
532 constraintElement.setAttribute( "version", "1.1.0" );
533 org.deegree.model.filterencoding.XMLFactory.appendFilter( constraintElement, query.getContraint() );
534 queryElement.appendChild( constraintElement );
535 }
536
537 // '<ogc:SortBy>'-element (optional)
538 SortProperty[] sortProperties = query.getSortProperties();
539 if ( sortProperties != null && sortProperties.length != 0 ) {
540 Element sortByElement = doc.createElementNS( OGCNS.toString(), "ogc:SortBy" );
541
542 // '<ogc:SortProperty>'-elements
543 for ( int j = 0; j < sortProperties.length; j++ ) {
544 Element sortPropertiesElement = doc.createElementNS( OGCNS.toString(), "ogc:SortProperty" );
545
546 // '<ogc:PropertyName>'-element (required)
547 Element propertyNameElement = doc.createElementNS( OGCNS.toString(), "ogc:PropertyName" );
548 appendPropertyPath( propertyNameElement, sortProperties[j].getSortProperty() );
549
550 // '<ogc:SortOrder>'-element (optional)
551 Element sortOrderElement = doc.createElementNS( OGCNS.toString(), "ogc:SortOrder" );
552 Node tn = doc.createTextNode( sortProperties[j].getSortOrder() ? "ASC" : "DESC" );
553 sortOrderElement.appendChild( tn );
554
555 sortPropertiesElement.appendChild( propertyNameElement );
556 sortPropertiesElement.appendChild( sortOrderElement );
557 sortByElement.appendChild( sortPropertiesElement );
558 }
559 queryElement.appendChild( sortByElement );
560 }
561 rootElement.appendChild( queryElement );
562 }
563 return getRecordsDocument;
564 }
565
566 /**
567 *
568 * @param rootElement
569 * the first node of the Docuement
570 * @param toBeInserted
571 * to which the typeNames attribute will be appended
572 * @param typeNames
573 * to be inserted into the toBeInserted element
574 * @param aliases
575 * may be <code>null</code>, if not each typeName must have exactly one alias defined, which will be
576 * inserted after the typename (e.g. typename=$o). If map must contain a mapping from variable to
577 * qualifiedName (e.g. [o, typeName]);
578 */
579 protected static void appendTypeNamesAttribute( Element rootElement, Element toBeInserted,
580 List<QualifiedName> typeNames, Map<String, QualifiedName> aliases ) {
581 if ( !typeNames.isEmpty() ) {
582 for ( QualifiedName qName : typeNames ) {
583 LOG.logDebug( "found typeName: " + qName );
584 }
585 LOG.logDebug( "for the element: " + toBeInserted.getNodeName()
586 + " we are trying to set the typeNames attribute." );
587 StringBuffer sb = new StringBuffer();
588 int count = 0;
589 for ( QualifiedName qName : typeNames ) {
590 if ( qName.getLocalName() != null ) {
591 URI ns = qName.getNamespace();
592 String prefix = qName.getPrefix();
593 if ( ns != null && prefix != null ) {
594 URI boundNS = null;
595 try {
596 boundNS = XMLTools.getNamespaceForPrefix( prefix, toBeInserted );
597 } catch ( URISyntaxException e ) {
598 // why for crying out loud an UriSyntax exception while lookin up stuff
599 // (without giving
600 // an
601 // uri).
602 }
603 LOG.logDebug( "ElementSetName/@typeNames: Found the namespace " + boundNS + " for the prefix: "
604 + prefix + " from typename (localname) : " + qName.getLocalName() );
605 if ( boundNS == null ) {
606 if ( CommonNamespaces.OASIS_EBRIMNS.equals( ns ) ) {
607 XMLTools.appendNSBinding( rootElement, "rim", ns );
608 LOG.logDebug( toBeInserted.getLocalName()
609 + "/@typeName: While no namespace was bound to the prefix: " + prefix
610 + " the namespace: " + ns
611 + " has been bound to 'rim' in the the root element." );
612 } else {
613 XMLTools.appendNSBinding( rootElement, prefix, ns );
614 LOG.logDebug( toBeInserted.getLocalName()
615 + "/@typeName: While no namespace was bound to the prefix: " + prefix
616 + " the namespace: " + ns + " has been bound to '" + prefix
617 + "' in the the root element." );
618 }
619
620 }
621 }
622 String typeName = prefix;
623 if ( typeName != null ) {
624 typeName += ":" + qName.getLocalName();
625 }
626 sb.append( typeName );
627 if ( aliases != null ) {
628 if ( aliases.containsValue( qName ) ) {
629 Set<String> keys = aliases.keySet();
630 for ( String key : keys ) {
631 if ( aliases.get( key ).equals( qName ) ) {
632 sb.append( "=" ).append( key );
633 aliases.remove( key );
634 break;
635 }
636 }
637 } else if ( aliases.size() > 0 ) {
638 LOG.logError( "No variable mapping found for typename: "
639 + typeName
640 + " this may not be, because every single typename must or no typename may have a variable!" );
641 }
642 }
643 if ( ++count < typeNames.size() ) {
644 sb.append( " " );
645 }
646 }
647 }
648 if ( !"null".equals( sb.toString().trim() ) && !"".equals( sb.toString().trim() ) ) {
649 LOG.logDebug( "for the element: " + toBeInserted.getNodeName()
650 + " we are settin the typeNames attribute to: " + sb.toString() );
651 toBeInserted.setAttribute( "typeNames", sb.toString() );
652 }
653 }
654 }
655
656 /**
657 * Exports a <code>GetRecordById</code> instance to a <code>GetRecordByIdDocument</code>.
658 *
659 * @param request
660 * @return DOM representation of the <code>GetRecordById</code>
661 * @throws XMLException
662 * if XML template could not be loaded
663 */
664 public static GetRecordByIdDocument export( GetRecordById request )
665 throws XMLException {
666
667 GetRecordByIdDocument getRecordByIdDoc = new GetRecordByIdDocument();
668 try {
669 getRecordByIdDoc.createEmptyDocument();
670 } catch ( Exception e ) {
671 throw new XMLException( e.getMessage() );
672 }
673 Element rootElement = getRecordByIdDoc.getRootElement();
674 Document doc = rootElement.getOwnerDocument();
675
676 // 'version'-attribute
677 rootElement.setAttribute( "version", request.getVersion() );
678
679 String[] ids = request.getIds();
680 for ( int i = 0; i < ids.length; i++ ) {
681 Element idElement = doc.createElementNS( CSWNS.toString(), "csw:Id" );
682 idElement.appendChild( doc.createTextNode( ids[i] ) );
683 rootElement.appendChild( idElement );
684 }
685
686 String elementSetName = request.getElementSetName();
687 if ( elementSetName != null ) {
688 Element esnElement = doc.createElementNS( CSWNS.toString(), "csw:ElementSetName" );
689 esnElement.appendChild( doc.createTextNode( elementSetName ) );
690 rootElement.appendChild( esnElement );
691 }
692
693 return getRecordByIdDoc;
694 }
695 }