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