001 // $HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/owscommon/XMLFactory.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2006 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 ---------------------------------------------------------------------------*/ 044 package org.deegree.owscommon; 045 046 import java.io.UnsupportedEncodingException; 047 import java.net.URI; 048 import java.net.URL; 049 import java.net.URLEncoder; 050 051 import org.deegree.framework.util.CharsetUtils; 052 import org.deegree.framework.xml.XMLFragment; 053 import org.deegree.framework.xml.XMLParsingException; 054 import org.deegree.framework.xml.XMLTools; 055 import org.deegree.model.metadata.iso19115.Address; 056 import org.deegree.model.metadata.iso19115.ContactInfo; 057 import org.deegree.model.metadata.iso19115.Keywords; 058 import org.deegree.model.metadata.iso19115.Linkage; 059 import org.deegree.model.metadata.iso19115.OnlineResource; 060 import org.deegree.model.metadata.iso19115.Phone; 061 import org.deegree.model.metadata.iso19115.TypeCode; 062 import org.deegree.ogcbase.CommonNamespaces; 063 import org.deegree.ogcwebservices.ExceptionDocument; 064 import org.deegree.ogcwebservices.ExceptionReport; 065 import org.deegree.ogcwebservices.OGCWebServiceException; 066 import org.deegree.ogcwebservices.getcapabilities.DCPType; 067 import org.deegree.ogcwebservices.getcapabilities.HTTP; 068 import org.deegree.ogcwebservices.getcapabilities.Operation; 069 import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata; 070 import org.deegree.ogcwebservices.getcapabilities.ServiceIdentification; 071 import org.deegree.ogcwebservices.getcapabilities.ServiceProvider; 072 import org.w3c.dom.Element; 073 074 /** 075 * Factory to create XML representations of components that are defined in the 076 * <code>OWS Common Implementation Capabilities Specification 0.3</code>. 077 * 078 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a> 079 * @author last edited by: $Author: aschmitz $ 080 * 081 * @version $Revision: 7975 $, $Date: 2007-08-10 09:38:27 +0200 (Fr, 10 Aug 2007) $ 082 */ 083 public class XMLFactory extends org.deegree.ogcbase.XMLFactory { 084 085 protected static final URI OWSNS = CommonNamespaces.OWSNS; 086 087 private static final String POGC = CommonNamespaces.OGC_PREFIX + ':'; 088 089 protected static final URI DEEGREECSWNS = CommonNamespaces.DEEGREECSW; 090 091 /** 092 * Exports an <tt>ExceptionReport</tt> to an XML Document as defined in the 093 * <code>OGC common implementation specification 0.2.0</code>. 094 * 095 * @param exr 096 * @return a new ServiceException document 097 */ 098 public static XMLFragment export( ExceptionReport exr ) { 099 100 ExceptionDocument eDoc = new ExceptionDocument(); 101 eDoc.createEmptyDocument(); 102 Element node = eDoc.getRootElement(); 103 104 for ( int i = 0; i < exr.getExceptions().length; i++ ) { 105 appendException( node, exr.getExceptions()[i], false ); 106 } 107 108 return eDoc; 109 } 110 111 /** 112 * @param exr 113 * @return a new ServiceException document 114 */ 115 public static XMLFragment exportNS( ExceptionReport exr ) { 116 117 ExceptionDocument eDoc = new ExceptionDocument(); 118 eDoc.createEmptyDocumentNS(); 119 Element node = eDoc.getRootElement(); 120 121 for ( int i = 0; i < exr.getExceptions().length; i++ ) { 122 appendException( node, exr.getExceptions()[i], true ); 123 } 124 125 return eDoc; 126 127 } 128 129 /** 130 * appends a xml representation of an <tt>OGCWebServiceException</tt> to the passed 131 * <tt>Element</tt> 132 * 133 * @param node 134 * @param ex 135 * @param namespace if true, the ogc prefix (bound to the ogc namespace) will be appended 136 */ 137 protected static void appendException( Element node, OGCWebServiceException ex, 138 boolean namespace ) { 139 140 if ( namespace ) { 141 node = XMLTools.appendElement( node, OGCNS, POGC + "ServiceException", ex.getMessage() ); 142 } else { 143 node = XMLTools.appendElement( node, null, "ServiceException", ex.getMessage() ); 144 } 145 146 if ( ex.getCode() != null ) { 147 node.setAttribute( "code", ex.getCode().value ); 148 } 149 String locator = ex.getLocator(); 150 try { 151 if ( locator != null ) { 152 locator = URLEncoder.encode( locator, CharsetUtils.getSystemCharset() ); 153 } else { 154 locator = "unknown"; 155 } 156 } catch ( UnsupportedEncodingException e ) { 157 //if catched why not do something -> setting locator to "unknown" 158 locator = "unknown"; 159 } 160 node.setAttribute( "locator", locator ); 161 } 162 163 /** 164 * Appends the DOM representation of the <code>ServiceIdentification</code>- section to the 165 * passed <code>Element</code>. 166 * 167 * @param root 168 * @param serviceIdentification 169 * @throws XMLParsingException 170 */ 171 protected static void appendServiceIdentification( Element root, 172 ServiceIdentification serviceIdentification ) { 173 174 // 'ServiceIdentification'-element 175 Element serviceIdentificationNode = XMLTools.appendElement( root, OWSNS, 176 "ows:ServiceIdentification" ); 177 178 // 'ServiceType'-element 179 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:ServiceType", 180 serviceIdentification.getServiceType().getCode() ); 181 182 // 'ServiceTypeVersion'-elements 183 String[] versions = serviceIdentification.getServiceTypeVersions(); 184 for ( int i = 0; i < versions.length; i++ ) { 185 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:ServiceTypeVersion", 186 versions[i] ); 187 } 188 189 // 'Title'-element 190 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:Title", 191 serviceIdentification.getTitle() ); 192 193 // 'Abstract'-element 194 if ( serviceIdentification.getAbstract() != null ) { 195 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:Abstract", 196 serviceIdentification.getAbstract() ); 197 } 198 199 // 'Keywords'-element 200 appendOWSKeywords( serviceIdentificationNode, serviceIdentification.getKeywords() ); 201 202 // 'Fees'-element 203 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:Fees", 204 serviceIdentification.getFees() ); 205 206 // 'AccessConstraints'-element 207 String[] constraints = serviceIdentification.getAccessConstraints(); 208 if ( constraints != null ) { 209 for ( int i = 0; i < constraints.length; i++ ) { 210 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:AccessConstraints", 211 constraints[i] ); 212 } 213 } 214 } 215 216 /** 217 * Appends a <code>ows:Keywords</code> -element for each <code>Keywords</code> object of the 218 * passed array to the passed <code>Element</code>. 219 * 220 * @param xmlNode 221 * @param keywords 222 */ 223 protected static void appendOWSKeywords( Element xmlNode, Keywords[] keywords ) { 224 if ( keywords != null ) { 225 for ( int i = 0; i < keywords.length; i++ ) { 226 Element node = XMLTools.appendElement( xmlNode, OWSNS, "ows:Keywords" ); 227 appendOWSKeywords( node, keywords[i] ); 228 } 229 } 230 } 231 232 /** 233 * Appends a <code>ows:Keywords</code> -element to the passed <code>Element</code> and fills 234 * it with the available keywords. 235 * 236 * @param xmlNode 237 * @param keywords 238 */ 239 protected static void appendOWSKeywords( Element xmlNode, Keywords keywords ) { 240 if ( keywords != null ) { 241 String[] kw = keywords.getKeywords(); 242 for ( int i = 0; i < kw.length; i++ ) { 243 XMLTools.appendElement( xmlNode, OWSNS, "ows:Keyword", kw[i] ); 244 } 245 TypeCode typeCode = keywords.getTypeCode(); 246 if ( typeCode != null ) { 247 Element node = XMLTools.appendElement( xmlNode, OWSNS, "ows:Type", 248 typeCode.getCode() ); 249 if ( typeCode.getCodeSpace() != null ) { 250 node.setAttribute( "codeSpace", typeCode.getCodeSpace().toString() ); 251 } 252 } 253 } 254 } 255 256 /** 257 * Appends the DOM representation of the <code>ServiceProvider</code>- section to the passed 258 * <code>Element</code>. 259 * 260 * @param root 261 * @param serviceProvider 262 * @throws XMLParsingException 263 */ 264 protected static void appendServiceProvider( Element root, ServiceProvider serviceProvider ) { 265 266 // 'ServiceProvider'-element 267 Element serviceProviderNode = XMLTools.appendElement( root, OWSNS, "ows:ServiceProvider" ); 268 269 // 'ProviderName'-element 270 XMLTools.appendElement( serviceProviderNode, OWSNS, "ows:ProviderName", 271 serviceProvider.getProviderName() ); 272 273 // 'ProviderSite'-element 274 if ( serviceProvider.getProviderSite() != null ) { 275 Element providerSiteNode = XMLTools.appendElement( serviceProviderNode, OWSNS, 276 "ows:ProviderSite" ); 277 appendSimpleLinkAttributes( providerSiteNode, serviceProvider.getProviderSite() ); 278 } 279 280 // 'ServiceContact'-element 281 Element serviceContactNode = XMLTools.appendElement( serviceProviderNode, OWSNS, 282 "ows:ServiceContact" ); 283 284 // 'IndividualName'-element 285 XMLTools.appendElement( serviceContactNode, OWSNS, "ows:IndividualName", 286 serviceProvider.getIndividualName() ); 287 288 // 'PositionName'-element 289 if ( serviceProvider.getPositionName() != null ) { 290 XMLTools.appendElement( serviceContactNode, OWSNS, "ows:PositionName", 291 serviceProvider.getPositionName() ); 292 } 293 294 // 'ContactInfo'-element 295 ContactInfo contactInfo = serviceProvider.getContactInfo(); 296 if ( contactInfo != null ) { 297 Element contactInfoNode = XMLTools.appendElement( serviceContactNode, OWSNS, 298 "ows:ContactInfo" ); 299 Phone phone = contactInfo.getPhone(); 300 if ( phone != null ) { 301 appendPhone( contactInfoNode, phone ); 302 } 303 Address address = contactInfo.getAddress(); 304 if ( address != null ) { 305 appendAddress( contactInfoNode, address ); 306 } 307 OnlineResource onlineResource = contactInfo.getOnLineResource(); 308 if ( onlineResource != null ) { 309 appendOnlineResource( contactInfoNode, "ows:OnlineResource", onlineResource, OWSNS ); 310 } 311 String hoursOfService = contactInfo.getHoursOfService(); 312 if ( hoursOfService != null ) { 313 XMLTools.appendElement( contactInfoNode, OWSNS, "ows:HoursOfService", 314 hoursOfService ); 315 } 316 String contactInstructions = contactInfo.getContactInstructions(); 317 if ( contactInstructions != null ) { 318 XMLTools.appendElement( contactInfoNode, OWSNS, "ows:ContactInstructions", 319 contactInstructions ); 320 } 321 } 322 TypeCode role = serviceProvider.getRole(); 323 if ( role != null ) { 324 Element roleElement = XMLTools.appendElement( serviceContactNode, OWSNS, "ows:Role", 325 role.getCode() ); 326 if ( role.getCodeSpace() != null ) { 327 roleElement.setAttribute( "codeSpace", role.getCodeSpace().toString() ); 328 } 329 } 330 } 331 332 /** 333 * Appends the DOM representation of the <code>Phone</code> -section to the passed 334 * <code>Element</code>. 335 * 336 * @param root 337 * @param phone 338 */ 339 protected static void appendPhone( Element root, Phone phone ) { 340 341 // 'Phone'-element 342 Element phoneNode = XMLTools.appendElement( root, OWSNS, "ows:Phone" ); 343 344 // 'Voice'-elements 345 String[] voiceNumbers = phone.getVoice(); 346 for ( int i = 0; i < voiceNumbers.length; i++ ) { 347 XMLTools.appendElement( phoneNode, OWSNS, "ows:Voice", voiceNumbers[i] ); 348 } 349 350 // 'Facsimile'-elements 351 String[] facsimileNumbers = phone.getFacsimile(); 352 for ( int i = 0; i < facsimileNumbers.length; i++ ) { 353 XMLTools.appendElement( phoneNode, OWSNS, "ows:Facsimile", facsimileNumbers[i] ); 354 } 355 } 356 357 /** 358 * Appends the DOM representation of the <code>Address</code> -section to the passed 359 * <code>Element</code>. 360 * 361 * @param root 362 * @param address 363 */ 364 protected static void appendAddress( Element root, Address address ) { 365 366 // 'Address'-element 367 Element addressNode = XMLTools.appendElement( root, OWSNS, "ows:Address" ); 368 369 // 'DeliveryPoint'-elements 370 String[] deliveryPoints = address.getDeliveryPoint(); 371 for ( int i = 0; i < deliveryPoints.length; i++ ) { 372 XMLTools.appendElement( addressNode, OWSNS, "ows:DeliveryPoint", deliveryPoints[i] ); 373 } 374 375 // 'City'-element 376 if ( address.getCity() != null ) { 377 XMLTools.appendElement( addressNode, OWSNS, "ows:City", address.getCity() ); 378 } 379 380 // 'AdministrativeArea'-element 381 if ( address.getAdministrativeArea() != null ) { 382 XMLTools.appendElement( addressNode, OWSNS, "ows:AdministrativeArea", 383 address.getAdministrativeArea() ); 384 } 385 386 // 'PostalCode'-element 387 if ( address.getPostalCode() != null ) { 388 XMLTools.appendElement( addressNode, OWSNS, "ows:PostalCode", address.getPostalCode() ); 389 } 390 391 // 'Country'-element 392 if ( address.getCountry() != null ) { 393 XMLTools.appendElement( addressNode, OWSNS, "ows:Country", address.getCountry() ); 394 } 395 396 // 'ElectronicMailAddress'-elements 397 String[] electronicMailAddresses = address.getElectronicMailAddress(); 398 if ( address.getElectronicMailAddress() != null ) { 399 for ( int i = 0; i < electronicMailAddresses.length; i++ ) { 400 XMLTools.appendElement( addressNode, OWSNS, "ows:ElectronicMailAddress", 401 electronicMailAddresses[i] ); 402 } 403 } 404 } 405 406 /** 407 * Appends the DOM representation of the <code>OperationsMetadata</code>- section to the 408 * passed <code>Element</code>. 409 * 410 * @param root 411 */ 412 protected static void appendOperationsMetadata( Element root, 413 OperationsMetadata operationsMetadata ) { 414 415 // 'ows:OperationsMetadata'-element 416 Element operationsMetadataNode = XMLTools.appendElement( root, OWSNS, 417 "ows:OperationsMetadata" ); 418 419 // append all Operations 420 Operation[] operations = operationsMetadata.getOperations(); 421 for ( int i = 0; i < operations.length; i++ ) { 422 Operation operation = operations[i]; 423 424 // 'ows:Operation'-element 425 Element operationElement = XMLTools.appendElement( operationsMetadataNode, OWSNS, 426 "ows:Operation" ); 427 operationElement.setAttribute( "name", operation.getName() ); 428 429 // 'ows:DCP'-elements 430 DCPType[] dcps = operation.getDCPs(); 431 for ( int j = 0; j < dcps.length; j++ ) { 432 appendDCP( operationElement, dcps[j] ); 433 } 434 435 // 'ows:Parameter'-elements 436 OWSDomainType[] parameters = operation.getParameters(); 437 for ( int j = 0; j < parameters.length; j++ ) { 438 appendParameter( operationElement, parameters[j], "ows:Parameter" ); 439 } 440 441 // 'ows:Metadata'-elements 442 Object[] metadata = operation.getMetadata(); 443 if ( metadata != null ) { 444 for ( int j = 0; j < metadata.length; j++ ) { 445 appendMetadata( operationElement, metadata[j] ); 446 } 447 } 448 } 449 450 // append general parameters 451 OWSDomainType[] parameters = operationsMetadata.getParameter(); 452 for ( int i = 0; i < parameters.length; i++ ) { 453 appendParameter( operationsMetadataNode, parameters[i], "ows:Parameter" ); 454 } 455 456 // append constraints 457 OWSDomainType[] constraints = operationsMetadata.getConstraints(); 458 for ( int i = 0; i < constraints.length; i++ ) { 459 appendParameter( operationsMetadataNode, constraints[i], "ows:Constraint" ); 460 } 461 } 462 463 /** 464 * Appends the DOM representation of a <code>DCPType</code> instance to the passed 465 * <code>Element</code>. 466 * 467 * @param root 468 * @param dcp 469 */ 470 protected static void appendDCP( Element root, DCPType dcp ) { 471 472 // 'ows:DCP'-element 473 Element dcpNode = XMLTools.appendElement( root, OWSNS, "ows:DCP" ); 474 475 // currently, the only supported DCP is HTTP! 476 if ( dcp.getProtocol() instanceof HTTP ) { 477 HTTP http = (HTTP) dcp.getProtocol(); 478 479 // 'ows:HTTP'-element 480 Element httpNode = XMLTools.appendElement( dcpNode, OWSNS, "ows:HTTP" ); 481 482 // 'ows:Get'-elements 483 URL[] getURLs = http.getGetOnlineResources(); 484 for ( int i = 0; i < getURLs.length; i++ ) { 485 appendOnlineResource( httpNode, "ows:Get", 486 new OnlineResource( new Linkage( getURLs[i] ) ), OWSNS ); 487 } 488 489 // 'ows:Post'-elements 490 URL[] postURLs = http.getPostOnlineResources(); 491 for ( int i = 0; i < postURLs.length; i++ ) { 492 appendOnlineResource( httpNode, "ows:Post", 493 new OnlineResource( new Linkage( postURLs[i] ) ), OWSNS ); 494 } 495 } 496 } 497 498 /** 499 * Appends the DOM representation of a <code>OWSDomainType</code> instance to the passed 500 * <code>Element</code>. 501 * 502 * @param root 503 * @param parameter 504 */ 505 protected static void appendParameter( Element root, OWSDomainType parameter, String elementName ) { 506 507 // 'ows:Parameter'-element 508 Element parameterNode = XMLTools.appendElement( root, OWSNS, elementName ); 509 parameterNode.setAttribute( "name", parameter.getName() ); 510 511 // 'ows:Value'-elements 512 String[] values = parameter.getValues(); 513 for ( int i = 0; i < values.length; i++ ) { 514 XMLTools.appendElement( parameterNode, OWSNS, "ows:Value", values[i] ); 515 } 516 } 517 518 /** 519 * Appends the DOM representation of a <code>Metadata</code> instance to the passed 520 * <code>Element</code>. 521 * 522 * @param root 523 * @param metadata 524 */ 525 protected static void appendMetadata( Element root, Object metadata ) { 526 527 // TODO 528 529 } 530 }