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 }