001 // $HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/wmps/capabilities/WMPSCapabilitiesDocument.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.wmps.capabilities; 037 038 import java.io.IOException; 039 import java.net.MalformedURLException; 040 import java.net.URI; 041 import java.net.URISyntaxException; 042 import java.net.URL; 043 import java.util.List; 044 045 import org.deegree.datatypes.Code; 046 import org.deegree.datatypes.xlink.SimpleLink; 047 import org.deegree.framework.log.ILogger; 048 import org.deegree.framework.log.LoggerFactory; 049 import org.deegree.framework.util.StringTools; 050 import org.deegree.framework.xml.XMLParsingException; 051 import org.deegree.framework.xml.XMLTools; 052 import org.deegree.model.crs.CRSFactory; 053 import org.deegree.model.crs.CoordinateSystem; 054 import org.deegree.model.crs.UnknownCRSException; 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.OnlineResource; 059 import org.deegree.model.metadata.iso19115.Phone; 060 import org.deegree.model.spatialschema.Envelope; 061 import org.deegree.model.spatialschema.GeometryFactory; 062 import org.deegree.model.spatialschema.Position; 063 import org.deegree.ogcbase.CommonNamespaces; 064 import org.deegree.ogcwebservices.getcapabilities.DCPType; 065 import org.deegree.ogcwebservices.getcapabilities.HTTP; 066 import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException; 067 import org.deegree.ogcwebservices.getcapabilities.MetadataURL; 068 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities; 069 import org.deegree.ogcwebservices.getcapabilities.Operation; 070 import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata; 071 import org.deegree.ogcwebservices.getcapabilities.Protocol; 072 import org.deegree.ogcwebservices.getcapabilities.ServiceIdentification; 073 import org.deegree.ogcwebservices.getcapabilities.ServiceProvider; 074 import org.deegree.ogcwebservices.wms.capabilities.Attribution; 075 import org.deegree.ogcwebservices.wms.capabilities.AuthorityURL; 076 import org.deegree.ogcwebservices.wms.capabilities.DataURL; 077 import org.deegree.ogcwebservices.wms.capabilities.Dimension; 078 import org.deegree.ogcwebservices.wms.capabilities.Extent; 079 import org.deegree.ogcwebservices.wms.capabilities.FeatureListURL; 080 import org.deegree.ogcwebservices.wms.capabilities.Identifier; 081 import org.deegree.ogcwebservices.wms.capabilities.Layer; 082 import org.deegree.ogcwebservices.wms.capabilities.LayerBoundingBox; 083 import org.deegree.ogcwebservices.wms.capabilities.LegendURL; 084 import org.deegree.ogcwebservices.wms.capabilities.LogoURL; 085 import org.deegree.ogcwebservices.wms.capabilities.ScaleHint; 086 import org.deegree.ogcwebservices.wms.capabilities.Style; 087 import org.deegree.ogcwebservices.wms.capabilities.StyleSheetURL; 088 import org.deegree.ogcwebservices.wms.capabilities.StyleURL; 089 import org.deegree.ogcwebservices.wms.capabilities.UserDefinedSymbolization; 090 import org.deegree.owscommon.OWSCommonCapabilitiesDocument; 091 import org.deegree.owscommon.OWSDomainType; 092 import org.w3c.dom.Element; 093 import org.w3c.dom.Node; 094 import org.xml.sax.SAXException; 095 096 /** 097 * Represents an XML capabilities document for an OGC WFS 1.1.0 compliant web service. 098 * 099 * @author <a href="mailto:deshmukh@lat-lon.de">Anup Deshmukh </a> 100 * 101 * @version 2.0 102 */ 103 public class WMPSCapabilitiesDocument extends OWSCommonCapabilitiesDocument { 104 105 private static final long serialVersionUID = -9098679671644329509L; 106 107 private static final ILogger LOG = LoggerFactory.getLogger( WMPSCapabilitiesDocument.class ); 108 109 protected static final URI WMPSNS = CommonNamespaces.WMPSNS; 110 111 private static final String XML_TEMPLATE = "WMPSCapabilitiesTemplate.xml"; 112 113 /** 114 * Creates a skeleton capabilities document that contains the mandatory elements only. 115 * 116 * @throws IOException 117 * @throws SAXException 118 */ 119 public void createEmptyDocument() 120 throws IOException, SAXException { 121 URL url = WMPSCapabilitiesDocument.class.getResource( XML_TEMPLATE ); 122 if ( url == null ) { 123 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." ); 124 } 125 load( url ); 126 } 127 128 /** 129 * Creates a class representation of the document. 130 * 131 * @return OGCCapabilities class representation of the configuration document 132 * @throws InvalidCapabilitiesException 133 */ 134 @Override 135 public OGCCapabilities parseCapabilities() 136 throws InvalidCapabilitiesException { 137 138 139 LOG.logDebug( "Parsing Capabilties Request." ); 140 ServiceIdentification serviceIdentification = null; 141 ServiceProvider serviceProvider = null; 142 UserDefinedSymbolization uds = null; 143 OperationsMetadata metadata = null; 144 Layer layer = null; 145 String version = parseVersion(); 146 try { 147 serviceIdentification = parseServiceIdentification(); 148 serviceProvider = parseServiceProvider(); 149 LOG.logDebug( "Retrieved serviceIdentification and serviceProvider information " 150 + "from the request." ); 151 metadata = parseOperationsMetadata(); 152 LOG.logDebug( "Retrieved metadData information from the request." ); 153 uds = parseUserDefinedSymbolization(); 154 Element layerElem = (Element) XMLTools.getRequiredNode( getRootElement(), 155 "./Capability/Layer", nsContext ); 156 LOG.logDebug( "Layer Element retrieved." ); 157 layer = parseLayers( layerElem, null ); 158 } catch ( XMLParsingException e ) { 159 String msg = "Error parsing the capabilities request to retrieve 'serviceIdentification'," 160 + " 'serviceProvider', 'metaData' and 'layer' " + e.getMessage(); 161 throw new InvalidCapabilitiesException( msg ); 162 } catch (UnknownCRSException e) { 163 throw new InvalidCapabilitiesException( getClass().getName(), e.getMessage() ); 164 } 165 WMPSCapabilities wmpsCapabilities = new WMPSCapabilities( version, serviceIdentification, 166 serviceProvider, uds, metadata, 167 layer ); 168 169 return wmpsCapabilities; 170 } 171 172 /** 173 * Parse the UserDefinedSymbolization 174 * 175 * @return UserDefinedSymbolization 176 * @throws XMLParsingException 177 */ 178 protected UserDefinedSymbolization parseUserDefinedSymbolization() 179 throws XMLParsingException { 180 181 182 String xPath = "./Capability/UserDefinedSymbolization/@SupportSLD"; 183 boolean supportSLD = XMLTools.getNodeAsBoolean( getRootElement(), xPath, nsContext, false ); 184 185 xPath = "./Capability/UserDefinedSymbolization/@UserLayer"; 186 boolean userLayer = XMLTools.getNodeAsBoolean( getRootElement(), xPath, nsContext, false ); 187 188 xPath = "./Capability/UserDefinedSymbolization/@UserStyle"; 189 boolean userStyle = XMLTools.getNodeAsBoolean( getRootElement(), xPath, nsContext, false ); 190 191 xPath = "./Capability/UserDefinedSymbolization/@RemoteWFS"; 192 boolean remoteWFS = XMLTools.getNodeAsBoolean( getRootElement(), xPath, nsContext, false ); 193 194 UserDefinedSymbolization uds = new UserDefinedSymbolization( supportSLD, userLayer, 195 remoteWFS, userStyle ); 196 197 198 return uds; 199 } 200 201 /** 202 * returns the services indentification read from the WMPS capabilities service section 203 * 204 * @return ServiceIdentification 205 * @throws XMLParsingException 206 */ 207 protected ServiceIdentification parseServiceIdentification() 208 throws XMLParsingException { 209 210 211 LOG.logDebug( "Parsing service identification parameter." ); 212 String name = XMLTools.getNodeAsString( getRootElement(), "./Service/Name", nsContext, null ); 213 String title = XMLTools.getNodeAsString( getRootElement(), "./Service/Title", nsContext, 214 name ); 215 String serviceAbstract = XMLTools.getNodeAsString( getRootElement(), "./Service/Abstract", 216 nsContext, null ); 217 218 String[] kw = XMLTools.getNodesAsStrings( getRootElement(), 219 "./Service/KeywordList/Keyword", nsContext ); 220 221 Keywords[] keywords = new Keywords[] { new Keywords( kw ) }; 222 223 String fees = XMLTools.getNodeAsString( getRootElement(), "./Service/Fees", nsContext, null ); 224 225 String[] accessConstraints = XMLTools.getNodesAsStrings( getRootElement(), 226 "./Service/AccessConstraints", 227 nsContext ); 228 229 String[] acceptedVersion = new String[] { "1.0.0" }; 230 Code code = new Code( "WMPS" ); 231 ServiceIdentification serviceIdentification = new ServiceIdentification( code, 232 acceptedVersion, 233 title, 234 serviceAbstract, 235 keywords, fees, 236 accessConstraints ); 237 238 return serviceIdentification; 239 } 240 241 /** 242 * returns WMPS contact informaion encapsulated within a <code>ServiceProvider</code> object 243 * 244 * @return ServiceProvider 245 * @throws XMLParsingException 246 */ 247 protected ServiceProvider parseServiceProvider() 248 throws XMLParsingException { 249 250 251 SimpleLink sLink = retrieveOnlineResourceSimpleLink(); 252 253 LOG.logDebug( "Parsing service provider parameter." ); 254 /** 255 * according to WMPS (draft) specification this element is mandatory but there are several 256 * services online which does not contain this element in its capabilities 257 */ 258 Node contactInfo = XMLTools.getRequiredNode( getRootElement(), 259 "./Service/ContactInformation", nsContext ); 260 261 String person = XMLTools.getRequiredNodeAsString( contactInfo, 262 "./ContactPersonPrimary/ContactPerson", 263 nsContext ); 264 String orga = XMLTools.getRequiredNodeAsString( 265 contactInfo, 266 "./ContactPersonPrimary/ContactOrganization", 267 nsContext ); 268 String position = XMLTools.getRequiredNodeAsString( contactInfo, "./ContactPosition", 269 nsContext ); 270 ContactInfo contact = parseContactInfo(); 271 272 ServiceProvider sp = new ServiceProvider( orga, sLink, person, position, contact, null ); 273 274 275 276 return sp; 277 } 278 279 /** 280 * Returns the SimpleLink from the Online Resource node in the Service element. 281 * 282 * @return SimpleLink 283 * @throws XMLParsingException 284 */ 285 private SimpleLink retrieveOnlineResourceSimpleLink() 286 throws XMLParsingException { 287 288 289 290 String simpleLink = XMLTools.getNodeAsString( getRootElement(), 291 "./Service/OnlineResource/@xlink:href", 292 nsContext, null ); 293 SimpleLink sLink = null; 294 if ( simpleLink != null ) { 295 try { 296 sLink = new SimpleLink( new URI( simpleLink ) ); 297 } catch ( URISyntaxException e ) { 298 throw new XMLParsingException( "Error parsing service online resource", e ); 299 } 300 } else { 301 try { 302 /** 303 * use default if no online resource is contained in the capabilities (see comment 304 * above) 305 */ 306 sLink = new SimpleLink( new URI( "http://www.opengeospatial.org/" ) ); 307 } catch ( URISyntaxException neverHappens ) { 308 neverHappens.printStackTrace(); 309 } 310 } 311 312 return sLink; 313 } 314 315 /** 316 * Parse Contact Information 317 * 318 * @return ContactInfo 319 * @throws XMLParsingException 320 */ 321 protected ContactInfo parseContactInfo() 322 throws XMLParsingException { 323 324 325 LOG.logDebug( "Parsing contact information parameter." ); 326 Node contactInfo = XMLTools.getNode( getRootElement(), "./Service/ContactInformation", 327 nsContext ); 328 String[] addr = XMLTools.getNodesAsStrings( contactInfo, "./ContactAddress/Address", 329 nsContext ); 330 // String addrType = XMLTools.getNodeAsString( contactInfo, "./ContactAddress/AddressType", 331 // nsContext, null ); 332 String city = XMLTools.getNodeAsString( contactInfo, "./ContactAddress/City", nsContext, 333 null ); 334 String state = XMLTools.getNodeAsString( contactInfo, "./ContactAddress/StateOrProvince", 335 nsContext, null ); 336 String pc = XMLTools.getNodeAsString( contactInfo, "./ContactAddress/PostCode", nsContext, 337 null ); 338 String country = XMLTools.getNodeAsString( contactInfo, "./ContactAddress/Country", 339 nsContext, null ); 340 String[] mail = XMLTools.getNodesAsStrings( contactInfo, "./ContactElectronicMailAddress", 341 nsContext ); 342 Address address = new Address( state, city, country, addr, mail, pc ); 343 344 String[] phone = XMLTools.getNodesAsStrings( contactInfo, "./ContactVoiceTelephone", 345 nsContext ); 346 String[] fax = XMLTools.getNodesAsStrings( contactInfo, "./ContactFacsimileTelephone", 347 nsContext ); 348 349 Phone ph = new Phone( fax, phone ); 350 351 ContactInfo cont = new ContactInfo( address, null, null, null, ph ); 352 353 354 return cont; 355 } 356 357 /** 358 * returns the services capabilitiy read from the WMPS capabilities file 359 * 360 * @return OperationsMetadata 361 * @throws XMLParsingException 362 */ 363 protected OperationsMetadata parseOperationsMetadata() 364 throws XMLParsingException { 365 366 367 LOG.logDebug( "Parsing operations metdata parameter." ); 368 Node opNode = XMLTools.getNode( getRootElement(), "./Capability/Request/GetCapabilities", 369 nsContext ); 370 371 Operation getCapabilities = parseOperation( opNode ); 372 LOG.logDebug( "Operation getCapabilities created for the GetCapabilities node." ); 373 374 opNode = XMLTools.getRequiredNode( getRootElement(), "./Capability/Request/PrintMap", 375 nsContext ); 376 377 Operation printMap = parseOperation( opNode ); 378 379 LOG.logDebug( "Operation printMap created for the PrintMap node." ); 380 381 WMPSOperationsMetadata metadata = new WMPSOperationsMetadata( getCapabilities, printMap ); 382 383 384 return metadata; 385 } 386 387 /** 388 * Creates an <tt>Operation</tt>-instance according to the contents of the DOM-subtree 389 * starting at the given <tt>Node</tt>. 390 * <p> 391 * Notice: operation to be parsed must be operations in sense of WMPS (draft). The method will 392 * return an OWSCommon Operation which encapsulates parsed WMPS operation 393 * <p> 394 * 395 * @param node 396 * the <tt>Element</tt> that describes an <tt>Operation</tt> 397 * @throws XMLParsingException 398 * if a syntactic or semantic error in the DOM-subtree is encountered 399 * @return the constructed <tt>Operation</tt>-instance 400 */ 401 protected Operation parseOperation( Node node ) 402 throws XMLParsingException { 403 404 405 LOG.logDebug( "Parsing Operation." ); 406 // use node name as name of the Operation to be defined 407 String name = node.getNodeName(); 408 String[] tmp = XMLTools.getRequiredNodesAsStrings( node, "./Format", nsContext ); 409 OWSDomainType owsDomainType = new OWSDomainType( "Format", tmp, null ); 410 OWSDomainType[] odt = new OWSDomainType[] { owsDomainType }; 411 412 List<Node> nl = XMLTools.getRequiredNodes( node, "./DCPType", nsContext ); 413 DCPType[] dcpTypes = new DCPType[nl.size()]; 414 for ( int i = 0; i < dcpTypes.length; i++ ) { 415 dcpTypes[i] = getDCP( (Element) nl.get( i ) ); 416 } 417 LOG.logDebug( "Creating operation with name, dcpTypes and OWSDomainType." ); 418 419 return new Operation( name, dcpTypes, odt ); 420 } 421 422 /** 423 * Creates a <code>DCPType</code> object from the passed <code>DCP</code> element. 424 * <p> 425 * NOTE: Currently the <code>OnlineResources</code> included in the <code>DCPType</code> are 426 * just stored as simple <code>URLs</code> (not as <code>OnLineResource</code> instances)! 427 * <p> 428 * NOTE: In an <code>OGCStandardCapabilitiesDocument</code> the <code>XLinks</code> (the 429 * <code>URLs</code>) are stored in separate elements (<code>OnlineResource</code>), in 430 * an <code>OGCCommonCapabilitiesDocument</code> they are the 431 * <code>Get<code>/<code>Post</code> elements themselves. 432 * 433 * @param element 434 * 435 * @return created <code>DCPType</code> 436 * @throws XMLParsingException 437 * 438 * @see org.deegree.ogcwebservices.getcapabilities.OGCStandardCapabilities 439 */ 440 @Override 441 protected DCPType getDCP( Element element ) 442 throws XMLParsingException { 443 444 DCPType dcpType = null; 445 try { 446 Element elem = (Element) XMLTools.getRequiredNode( element, "HTTP", nsContext ); 447 List<Node> nl = XMLTools.getNodes( elem, "Get", nsContext ); 448 449 URL[] get = new URL[nl.size()]; 450 for ( int i = 0; i < get.length; i++ ) { 451 String s = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@xlink:href", 452 nsContext, null ); 453 if ( s == null ) { 454 s = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), 455 "./OnlineResource/@xlink:href", nsContext ); 456 } 457 get[i] = new URL( s ); 458 } 459 nl = XMLTools.getNodes( elem, "Post", nsContext ); 460 461 URL[] post = new URL[nl.size()]; 462 for ( int i = 0; i < post.length; i++ ) { 463 String s = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@xlink:href", 464 nsContext, null ); 465 if ( s == null ) { 466 s = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), 467 "./OnlineResource/@xlink:href", nsContext ); 468 } 469 post[i] = new URL( s ); 470 } 471 Protocol protocol = new HTTP( get, post ); 472 dcpType = new DCPType( protocol ); 473 } catch ( MalformedURLException e ) { 474 throw new XMLParsingException( "Couldn't parse DCPType onlineresource URL about: " 475 + StringTools.stackTraceToString( e ) ); 476 } 477 478 return dcpType; 479 } 480 481 /** 482 * returns the layers offered by the WMPS 483 * 484 * @param layerElem 485 * @param parent 486 * @return Layer 487 * @throws XMLParsingException 488 * @throws UnknownCRSException 489 */ 490 protected Layer parseLayers( Element layerElem, Layer parent ) 491 throws XMLParsingException, UnknownCRSException { 492 493 494 boolean queryable = XMLTools.getNodeAsBoolean( layerElem, "./@queryable", nsContext, false ); 495 496 int cascaded = XMLTools.getNodeAsInt( layerElem, "./@cascaded", nsContext, 0 ); 497 boolean opaque = XMLTools.getNodeAsBoolean( layerElem, "./@opaque", nsContext, false ); 498 boolean noSubsets = XMLTools.getNodeAsBoolean( layerElem, "./@noSubsets", nsContext, false ); 499 int fixedWidth = XMLTools.getNodeAsInt( layerElem, "./@fixedWidth", nsContext, 0 ); 500 int fixedHeight = XMLTools.getNodeAsInt( layerElem, "./@fixedHeight", nsContext, 0 ); 501 String name = XMLTools.getNodeAsString( layerElem, "./Name", nsContext, null ); 502 String title = XMLTools.getRequiredNodeAsString( layerElem, "./Title", nsContext ); 503 String layerAbstract = XMLTools.getNodeAsString( layerElem, "./Abstract", nsContext, null ); 504 String[] keywords = XMLTools.getNodesAsStrings( layerElem, "./KeywordList/Keyword", 505 nsContext ); 506 String[] srs = XMLTools.getNodesAsStrings( layerElem, "./SRS", nsContext ); 507 508 List<Node> nl = XMLTools.getNodes( layerElem, "./BoundingBox", nsContext ); 509 // TODO replace with Envelope 510 LayerBoundingBox[] bboxes = null; 511 if ( nl.size() == 0 && parent != null ) { 512 // inherit BoundingBoxes from parent layer 513 bboxes = parent.getBoundingBoxes(); 514 } else { 515 bboxes = parseLayerBoundingBoxes( nl ); 516 } 517 518 Element llBox = (Element) XMLTools.getNode( layerElem, "./LatLonBoundingBox", nsContext ); 519 Envelope llBoundingBox = null; 520 521 if ( llBox == null && parent != null ) { 522 // inherit LatLonBoundingBox parent layer 523 llBoundingBox = parent.getLatLonBoundingBox(); 524 } else if ( llBox != null ) { 525 llBoundingBox = parseLatLonBoundingBox( llBox ); 526 } else { 527 /** Default crs = EPSG:4326 */ 528 CoordinateSystem crs = CRSFactory.create( "EPSG:4326" ); 529 llBoundingBox = GeometryFactory.createEnvelope( -180, -90, 180, 90, crs ); 530 } 531 532 Dimension[] dimensions = parseDimensions( layerElem ); 533 534 Extent[] extents = parseExtents( layerElem ); 535 536 Attribution attribution = parseAttribution( layerElem ); 537 538 AuthorityURL[] authorityURLs = parseAuthorityURLs( layerElem ); 539 540 MetadataURL[] metadataURLs = parseMetadataURLs( layerElem ); 541 542 DataURL[] dataURLs = parseDataURL( layerElem ); 543 544 Identifier[] identifiers = parseIdentifiers( layerElem ); 545 546 FeatureListURL[] featureListURLs = parseFeatureListURL( layerElem ); 547 548 Style[] styles = parseStyles( layerElem ); 549 550 ScaleHint scaleHint = parseScaleHint( layerElem ); 551 552 Layer layer = new Layer( queryable, cascaded, opaque, noSubsets, fixedWidth, fixedHeight, 553 name, title, layerAbstract, llBoundingBox, attribution, scaleHint, 554 keywords, srs, bboxes, dimensions, extents, authorityURLs, 555 identifiers, metadataURLs, dataURLs, featureListURLs, styles, 556 null, null, parent ); 557 558 // get Child layers 559 nl = XMLTools.getNodes( layerElem, "./Layer", nsContext ); 560 Layer[] layers = new Layer[nl.size()]; 561 for ( int i = 0; i < layers.length; i++ ) { 562 layers[i] = parseLayers( (Element) nl.get( i ), layer ); 563 } 564 565 // set child layers 566 layer.setLayer( layers ); 567 568 569 return layer; 570 } 571 572 /** 573 * Parse Dimensions 574 * 575 * @param layerElem 576 * @return Dimension[] 577 * @throws XMLParsingException 578 */ 579 protected Dimension[] parseDimensions( Element layerElem ) 580 throws XMLParsingException { 581 582 583 List<Node> nl = XMLTools.getNodes( layerElem, "./Dimension", nsContext ); 584 Dimension[] dimensions = new Dimension[nl.size()]; 585 for ( int i = 0; i < dimensions.length; i++ ) { 586 String name = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@name", nsContext, null ); 587 String units = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@units", nsContext, 588 null ); 589 String unitSymbol = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@unitSymbol", 590 nsContext, null ); 591 dimensions[i] = new Dimension( name, units, unitSymbol ); 592 } 593 594 595 return dimensions; 596 } 597 598 /** 599 * Parse Extents 600 * 601 * @param layerElem 602 * @return Extent[] 603 * @throws XMLParsingException 604 */ 605 protected Extent[] parseExtents( Element layerElem ) 606 throws XMLParsingException { 607 608 609 List<Node> nl = XMLTools.getNodes( layerElem, "./Extent", nsContext ); 610 Extent[] extents = new Extent[nl.size()]; 611 for ( int i = 0; i < extents.length; i++ ) { 612 String name = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@name", nsContext, null ); 613 String deflt = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@default", nsContext, 614 null ); 615 boolean nearestValue = XMLTools.getNodeAsBoolean( (Node) nl.get( i ), 616 "./@nearestValue", nsContext, false ); 617 String value = XMLTools.getNodeAsString( (Node) nl.get( i ), ".", nsContext, "" ); 618 extents[i] = new Extent( name, deflt, nearestValue, value ); 619 } 620 621 622 return extents; 623 } 624 625 /** 626 * Parse Attribution 627 * 628 * @param layerElem 629 * @return Attribution 630 * @throws XMLParsingException 631 */ 632 protected Attribution parseAttribution( Element layerElem ) 633 throws XMLParsingException { 634 635 636 Attribution attribution = null; 637 Node node = XMLTools.getNode( layerElem, "./Attribution", nsContext ); 638 if ( node != null ) { 639 String title = XMLTools.getRequiredNodeAsString( layerElem, "./Attribution/Title", 640 nsContext ); 641 Node onlineR = XMLTools.getRequiredNode( node, "./OnlineResource", nsContext ); 642 OnlineResource onLineResource = parseOnLineResource( (Element) onlineR ); 643 node = XMLTools.getNode( node, "./LogoURL", nsContext ); 644 LogoURL logoURL = null; 645 if ( node != null ) { 646 int width = XMLTools.getRequiredNodeAsInt( node, "./@width", nsContext ); 647 int height = XMLTools.getRequiredNodeAsInt( node, "./@height", nsContext ); 648 String format = XMLTools.getRequiredNodeAsString( node, "./Format", nsContext ); 649 onlineR = XMLTools.getRequiredNode( node, "./OnlineResource", nsContext ); 650 OnlineResource logoOR = parseOnLineResource( (Element) onlineR ); 651 logoURL = new LogoURL( width, height, format, logoOR.getLinkage().getHref() ); 652 } 653 attribution = new Attribution( title, onLineResource.getLinkage().getHref(), logoURL ); 654 } 655 656 657 return attribution; 658 } 659 660 /** 661 * Parse AuthorityURL 662 * 663 * @param layerElem 664 * @return AuthorityURL[] 665 * @throws XMLParsingException 666 */ 667 protected AuthorityURL[] parseAuthorityURLs( Element layerElem ) 668 throws XMLParsingException { 669 670 671 List<Node> nl = XMLTools.getNodes( layerElem, "./AuthorityURL", nsContext ); 672 AuthorityURL[] authorityURLs = new AuthorityURL[nl.size()]; 673 for ( int i = 0; i < authorityURLs.length; i++ ) { 674 String name = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@name", 675 nsContext ); 676 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), 677 "./OnlineResource", nsContext ); 678 OnlineResource olr = parseOnLineResource( tmp ); 679 authorityURLs[i] = new AuthorityURL( name, olr.getLinkage().getHref() ); 680 } 681 682 683 return authorityURLs; 684 } 685 686 /** 687 * Parse MetadataURL 688 * 689 * @param layerElem 690 * @return MetadataURL[] 691 * @throws XMLParsingException 692 */ 693 protected MetadataURL[] parseMetadataURLs( Element layerElem ) 694 throws XMLParsingException { 695 696 697 List<Node> nl = XMLTools.getNodes( layerElem, "./MetadataURL", nsContext ); 698 MetadataURL[] metadataURL = new MetadataURL[nl.size()]; 699 for ( int i = 0; i < metadataURL.length; i++ ) { 700 String type = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@type", 701 nsContext ); 702 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Format", 703 nsContext ); 704 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), 705 "./OnlineResource", nsContext ); 706 OnlineResource olr = parseOnLineResource( tmp ); 707 metadataURL[i] = new MetadataURL( type, format, olr.getLinkage().getHref() ); 708 709 } 710 711 712 return metadataURL; 713 } 714 715 /** 716 * Parse Data URL 717 * 718 * @param layerElem 719 * @return DataURL[] 720 * @throws XMLParsingException 721 */ 722 protected DataURL[] parseDataURL( Element layerElem ) 723 throws XMLParsingException { 724 725 726 List<Node> nl = XMLTools.getNodes( layerElem, "./DataURL", nsContext ); 727 DataURL[] dataURL = new DataURL[nl.size()]; 728 for ( int i = 0; i < dataURL.length; i++ ) { 729 730 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Format", 731 nsContext ); 732 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), 733 "./OnlineResource", nsContext ); 734 OnlineResource olr = parseOnLineResource( tmp ); 735 dataURL[i] = new DataURL( format, olr.getLinkage().getHref() ); 736 737 } 738 739 740 return dataURL; 741 } 742 743 /** 744 * Parse FeatureListURL 745 * 746 * @param layerElem 747 * @return FeatureListURL[] 748 * @throws XMLParsingException 749 */ 750 protected FeatureListURL[] parseFeatureListURL( Element layerElem ) 751 throws XMLParsingException { 752 753 754 List<Node> nl = XMLTools.getNodes( layerElem, "./FeatureListURL", nsContext ); 755 FeatureListURL[] flURL = new FeatureListURL[nl.size()]; 756 for ( int i = 0; i < flURL.length; i++ ) { 757 758 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Format", 759 nsContext ); 760 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), 761 "./OnlineResource", nsContext ); 762 OnlineResource olr = parseOnLineResource( tmp ); 763 flURL[i] = new FeatureListURL( format, olr.getLinkage().getHref() ); 764 765 } 766 767 768 return flURL; 769 } 770 771 /** 772 * Parse Styles 773 * 774 * @param layerElem 775 * @return Style[] 776 * @throws XMLParsingException 777 */ 778 protected Style[] parseStyles( Element layerElem ) 779 throws XMLParsingException { 780 781 782 List<Node> nl = XMLTools.getNodes( layerElem, "./Style", nsContext ); 783 Style[] styles = new Style[nl.size()]; 784 for ( int i = 0; i < styles.length; i++ ) { 785 String name = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Name", nsContext ); 786 String title = XMLTools.getNodeAsString( (Node) nl.get( i ), "./Title", nsContext, null ); 787 String styleAbstract = XMLTools.getNodeAsString( (Node) nl.get( i ), "./Abstract", 788 nsContext, null ); 789 LegendURL[] legendURLs = parseLegendURL( (Node) nl.get( i ) ); 790 StyleURL styleURL = parseStyleURL( (Node) nl.get( i ) ); 791 StyleSheetURL styleSheetURL = parseStyleSheetURL( (Node) nl.get( i ) ); 792 793 styles[i] = new Style( name, title, styleAbstract, legendURLs, styleSheetURL, styleURL, 794 null ); 795 } 796 797 798 return styles; 799 } 800 801 /** 802 * Parse Legend URL 803 * 804 * @param node 805 * @return LegendURL[] 806 * @throws XMLParsingException 807 */ 808 protected LegendURL[] parseLegendURL( Node node ) 809 throws XMLParsingException { 810 811 812 List<Node> nl = XMLTools.getNodes( node, "./LegendURL", nsContext ); 813 LegendURL[] lURL = new LegendURL[nl.size()]; 814 for ( int i = 0; i < lURL.length; i++ ) { 815 int width = XMLTools.getRequiredNodeAsInt( (Node) nl.get( i ), "./@width", nsContext ); 816 int height = XMLTools.getRequiredNodeAsInt( (Node) nl.get( i ), "./@height", nsContext ); 817 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Format", 818 nsContext ); 819 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), 820 "./OnlineResource", nsContext ); 821 OnlineResource olr = parseOnLineResource( tmp ); 822 lURL[i] = new LegendURL( width, height, format, olr.getLinkage().getHref() ); 823 824 } 825 826 827 return lURL; 828 } 829 830 /** 831 * Parse Style URL 832 * 833 * @param node 834 * @return StyleURL 835 * @throws XMLParsingException 836 */ 837 protected StyleURL parseStyleURL( Node node ) 838 throws XMLParsingException { 839 840 841 StyleURL styleURL = null; 842 Node styleNode = XMLTools.getNode( node, "./StyleURL", nsContext ); 843 844 if ( styleNode != null ) { 845 String format = XMLTools.getRequiredNodeAsString( styleNode, "./Format", nsContext ); 846 Element tmp = (Element) XMLTools.getRequiredNode( styleNode, "./OnlineResource", 847 nsContext ); 848 OnlineResource olr = parseOnLineResource( tmp ); 849 styleURL = new StyleURL( format, olr.getLinkage().getHref() ); 850 851 } 852 853 854 return styleURL; 855 } 856 857 /** 858 * Parse Style Sheet URL 859 * 860 * @param node 861 * @return StyleSheetURL 862 * @throws XMLParsingException 863 */ 864 protected StyleSheetURL parseStyleSheetURL( Node node ) 865 throws XMLParsingException { 866 867 868 StyleSheetURL styleSheetURL = null; 869 Node styleNode = XMLTools.getNode( node, "./StyleSheetURL", nsContext ); 870 871 if ( styleNode != null ) { 872 String format = XMLTools.getRequiredNodeAsString( styleNode, "./Format", nsContext ); 873 Element tmp = (Element) XMLTools.getRequiredNode( styleNode, "./OnlineResource", 874 nsContext ); 875 OnlineResource olr = parseOnLineResource( tmp ); 876 styleSheetURL = new StyleSheetURL( format, olr.getLinkage().getHref() ); 877 878 } 879 880 881 return styleSheetURL; 882 } 883 884 /** 885 * Parse Scale Hint 886 * 887 * @param layerElem 888 * @return ScaleHint 889 * @throws XMLParsingException 890 */ 891 protected ScaleHint parseScaleHint( Element layerElem ) 892 throws XMLParsingException { 893 894 895 ScaleHint scaleHint = null; 896 897 Node scNode = XMLTools.getNode( layerElem, "./ScaleHint", nsContext ); 898 if ( scNode != null ) { 899 double mn = XMLTools.getNodeAsDouble( scNode, "./@min", nsContext, 0 ); 900 double mx = XMLTools.getNodeAsDouble( scNode, "./@max", nsContext, Double.MAX_VALUE ); 901 scaleHint = new ScaleHint( mn, mx ); 902 } else { 903 // set default value to avoid NullPointerException 904 // when accessing a layers scalehint 905 scaleHint = new ScaleHint( 0, Double.MAX_VALUE ); 906 } 907 908 909 return scaleHint; 910 } 911 912 /** 913 * Parse Identifiers 914 * 915 * @param layerElem 916 * @return Identifier[] 917 * @throws XMLParsingException 918 */ 919 protected Identifier[] parseIdentifiers( Element layerElem ) 920 throws XMLParsingException { 921 922 923 List<Node> nl = XMLTools.getNodes( layerElem, "./Identifier", nsContext ); 924 Identifier[] identifiers = new Identifier[nl.size()]; 925 for ( int i = 0; i < identifiers.length; i++ ) { 926 String value = XMLTools.getStringValue( (Node) nl.get( i ) ); 927 String authority = XMLTools.getNodeAsString( layerElem, "./@authority", nsContext, null ); 928 identifiers[i] = new Identifier( value, authority ); 929 } 930 931 932 return identifiers; 933 } 934 935 /** 936 * Parse Layer Bounding Boxes 937 * 938 * @param nl 939 * @return LayerBoundingBox[] 940 * @throws XMLParsingException 941 */ 942 protected LayerBoundingBox[] parseLayerBoundingBoxes( List<Node> nl ) 943 throws XMLParsingException { 944 945 LayerBoundingBox[] llBoxes = new LayerBoundingBox[nl.size()]; 946 for ( int i = 0; i < llBoxes.length; i++ ) { 947 double minx = XMLTools.getRequiredNodeAsDouble( (Node) nl.get( i ), "./@minx", 948 nsContext ); 949 double maxx = XMLTools.getRequiredNodeAsDouble( (Node) nl.get( i ), "./@maxx", 950 nsContext ); 951 double miny = XMLTools.getRequiredNodeAsDouble( (Node) nl.get( i ), "./@miny", 952 nsContext ); 953 double maxy = XMLTools.getRequiredNodeAsDouble( (Node) nl.get( i ), "./@maxy", 954 nsContext ); 955 double resx = XMLTools.getNodeAsDouble( (Node) nl.get( i ), "./@resx", nsContext, -1 ); 956 double resy = XMLTools.getNodeAsDouble( (Node) nl.get( i ), "./@resx", nsContext, -1 ); 957 String srs = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@SRS", nsContext ); 958 Position min = GeometryFactory.createPosition( minx, miny ); 959 Position max = GeometryFactory.createPosition( maxx, maxy ); 960 llBoxes[i] = new LayerBoundingBox( min, max, srs, resx, resy ); 961 } 962 963 return llBoxes; 964 } 965 966 /** 967 * Parse Lat Lon Bounding Box 968 * 969 * @param llBox 970 * @return Envelope 971 * @throws XMLParsingException 972 * @throws UnknownCRSException 973 */ 974 protected Envelope parseLatLonBoundingBox( Element llBox ) 975 throws XMLParsingException, UnknownCRSException { 976 977 978 double minx = XMLTools.getRequiredNodeAsDouble( llBox, "./@minx", nsContext ); 979 double maxx = XMLTools.getRequiredNodeAsDouble( llBox, "./@maxx", nsContext ); 980 double miny = XMLTools.getRequiredNodeAsDouble( llBox, "./@miny", nsContext ); 981 double maxy = XMLTools.getRequiredNodeAsDouble( llBox, "./@maxy", nsContext ); 982 /** default crs = EPSG:4326 */ 983 CoordinateSystem crs = CRSFactory.create( "EPSG:4326" ); 984 Envelope env = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, crs ); 985 986 987 return env; 988 } 989 990 }