001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/ogcwebservices/wms/capabilities/WMSCapabilitiesDocument_1_3_0.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.wms.capabilities; 037 038 import static org.deegree.framework.xml.XMLTools.getElements; 039 040 import java.io.IOException; 041 import java.net.MalformedURLException; 042 import java.net.URI; 043 import java.net.URISyntaxException; 044 import java.net.URL; 045 import java.util.ArrayList; 046 import java.util.Arrays; 047 import java.util.Date; 048 import java.util.List; 049 050 import org.deegree.datatypes.Code; 051 import org.deegree.datatypes.QualifiedName; 052 import org.deegree.datatypes.values.TypedLiteral; 053 import org.deegree.framework.log.ILogger; 054 import org.deegree.framework.log.LoggerFactory; 055 import org.deegree.framework.util.StringTools; 056 import org.deegree.framework.xml.XMLParsingException; 057 import org.deegree.framework.xml.XMLTools; 058 import org.deegree.i18n.Messages; 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.CitedResponsibleParty; 064 import org.deegree.model.metadata.iso19115.Constraints; 065 import org.deegree.model.metadata.iso19115.ContactInfo; 066 import org.deegree.model.metadata.iso19115.Keywords; 067 import org.deegree.model.metadata.iso19115.Linkage; 068 import org.deegree.model.metadata.iso19115.OnlineResource; 069 import org.deegree.model.metadata.iso19115.Phone; 070 import org.deegree.model.spatialschema.Envelope; 071 import org.deegree.model.spatialschema.GeometryFactory; 072 import org.deegree.model.spatialschema.Position; 073 import org.deegree.ogcbase.CommonNamespaces; 074 import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException; 075 import org.deegree.ogcwebservices.getcapabilities.MetadataURL; 076 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities; 077 import org.deegree.owscommon_new.DCP; 078 import org.deegree.owscommon_new.DomainType; 079 import org.deegree.owscommon_new.HTTP; 080 import org.deegree.owscommon_new.Operation; 081 import org.deegree.owscommon_new.OperationsMetadata; 082 import org.deegree.owscommon_new.Parameter; 083 import org.deegree.owscommon_new.ServiceIdentification; 084 import org.deegree.owscommon_new.ServiceProvider; 085 import org.w3c.dom.Element; 086 import org.w3c.dom.Node; 087 import org.xml.sax.SAXException; 088 089 /** 090 * <code>WMSCapabilitiesDocument_1_3_0</code> is a parser class for capabilities documents according to the OGC WMS 091 * 1.3.0 specification. 092 * 093 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a> 094 * @author last edited by: $Author: mschneider $ 095 * 096 * @version 2.0, $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $ 097 * 098 * @since 2.0 099 */ 100 101 public class WMSCapabilitiesDocument_1_3_0 extends WMSCapabilitiesDocument { 102 103 private static final long serialVersionUID = -5085466301546020723L; 104 105 private static final String XML_TEMPLATE = "WMSCapabilitiesTemplate_1_3_0.xml"; 106 107 private static final ILogger LOG = LoggerFactory.getLogger( WMSCapabilitiesDocument_1_3_0.class ); 108 109 private static final String PWMS = CommonNamespaces.WMS_PREFIX + ":"; 110 111 private static final String PSLD = CommonNamespaces.SLD_PREFIX + ":"; 112 113 /* 114 * Just using a different XML_TEMPLATE. 115 */ 116 @Override 117 public void createEmptyDocument() 118 throws IOException, SAXException { 119 120 URL url = WMSCapabilitiesDocument.class.getResource( XML_TEMPLATE ); 121 if ( url == null ) { 122 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." ); 123 } 124 load( url ); 125 } 126 127 @Override 128 protected List<String> parseExceptionFormats( Element elem ) 129 throws XMLParsingException { 130 String[] formats = XMLTools.getRequiredNodesAsStrings( elem, PWMS + "Format", nsContext ); 131 return Arrays.asList( formats ); 132 } 133 134 /* 135 * Prefix added, not parsing UserDefinedSymbolization. Parsing new LayerLimit, MaxWidth, MaxHeight elements. 136 */ 137 @Override 138 public OGCCapabilities parseCapabilities() 139 throws InvalidCapabilitiesException { 140 ServiceIdentification serviceIdentification = null; 141 ServiceProvider serviceProvider = null; 142 OperationsMetadata metadata = null; 143 Layer layer = null; 144 String version = parseVersion(); 145 String updateSeq = parseUpdateSequence(); 146 List<String> exceptions; 147 148 Element root = getRootElement(); 149 150 int layerLimit = 0; 151 int maxWidth = 0; 152 int maxHeight = 0; 153 154 try { 155 Element serviceElement = (Element) XMLTools.getRequiredNode( root, PWMS + "Service", nsContext ); 156 157 layerLimit = XMLTools.getNodeAsInt( serviceElement, PWMS + "LayerLimit", nsContext, 0 ); 158 maxWidth = XMLTools.getNodeAsInt( serviceElement, PWMS + "MaxWidth", nsContext, 0 ); 159 maxHeight = XMLTools.getNodeAsInt( serviceElement, PWMS + "MaxHeight", nsContext, 0 ); 160 161 serviceIdentification = parseServiceIdentification(); 162 serviceProvider = parseServiceProvider(); 163 metadata = parseOperationsMetadata(); 164 165 Element exceptionElement = XMLTools.getRequiredElement( getRootElement(), PWMS + "Capability/" + PWMS 166 + "Exception", nsContext ); 167 exceptions = parseExceptionFormats( exceptionElement ); 168 169 Element layerElem = (Element) XMLTools.getRequiredNode( root, PWMS + "Capability/" + PWMS + "Layer", 170 nsContext ); 171 layer = parseLayers( layerElem, null, null ); 172 } catch ( XMLParsingException e ) { 173 LOG.logError( e.getLocalizedMessage(), e ); 174 throw new InvalidCapabilitiesException( e.getMessage() + StringTools.stackTraceToString( e ) ); 175 } catch ( Exception e ) { 176 LOG.logError( e.getLocalizedMessage(), e ); 177 throw new InvalidCapabilitiesException( e.getMessage() + StringTools.stackTraceToString( e ) ); 178 } 179 180 WMSCapabilities_1_3_0 wmsCapabilities = new WMSCapabilities_1_3_0( version, updateSeq, serviceIdentification, 181 serviceProvider, metadata, layer, 182 layerLimit, maxWidth, maxHeight, exceptions ); 183 return wmsCapabilities; 184 } 185 186 /* 187 * Prefix added. Name is now "WMS" instead of "OGC:WMS" 188 */ 189 @Override 190 protected ServiceIdentification parseServiceIdentification() 191 throws XMLParsingException { 192 193 String name = XMLTools.getNodeAsString( getRootElement(), PWMS + "Service/" + PWMS + "Name", nsContext, null ); 194 String title = XMLTools.getNodeAsString( getRootElement(), PWMS + "Service/" + PWMS + "Title", nsContext, name ); 195 String serviceAbstract = XMLTools.getNodeAsString( getRootElement(), PWMS + "Service/" + PWMS + "Abstract", 196 nsContext, null ); 197 198 String[] kw = XMLTools.getNodesAsStrings( getRootElement(), PWMS + "Service/" + PWMS + "KeywordList/" + PWMS 199 + "Keyword", nsContext ); 200 201 Keywords[] keywordArray = new Keywords[] { new Keywords( kw ) }; 202 List<Keywords> keywords = Arrays.asList( keywordArray ); 203 204 String fees = XMLTools.getNodeAsString( getRootElement(), PWMS + "Service/" + PWMS + "Fees", nsContext, null ); 205 206 List<Constraints> accessConstraints = new ArrayList<Constraints>(); 207 208 String[] constraints = XMLTools.getNodesAsStrings( getRootElement(), PWMS + "Service/" + PWMS 209 + "AccessConstraints", nsContext ); 210 211 for ( String constraint : constraints ) { 212 List<String> limits = new ArrayList<String>(); 213 limits.add( constraint ); 214 accessConstraints.add( new Constraints( fees, null, null, null, limits, null, null, null ) ); 215 } 216 217 List<String> versions = new ArrayList<String>(); 218 versions.add( "1.0.0" ); 219 versions.add( "1.1.0" ); 220 versions.add( "1.1.1" ); 221 versions.add( "1.2.0" ); 222 versions.add( "1.3.0" ); 223 224 ServiceIdentification serviceIdentification = new ServiceIdentification( 225 new Code( "WMS" ), 226 versions, 227 title, 228 null, 229 new Date( System.currentTimeMillis() ), 230 title, serviceAbstract, keywords, 231 accessConstraints ); 232 233 return serviceIdentification; 234 } 235 236 /* 237 * Prefix added. 238 */ 239 @Override 240 protected ServiceProvider parseServiceProvider() 241 throws XMLParsingException { 242 Node ci = XMLTools.getNode( getRootElement(), PWMS + "Service/" + PWMS + "ContactInformation", nsContext ); 243 244 // according to WMS 1.1.1 specification this element is mandatory 245 // but there are several services online which does not contain 246 // this element in its capabilities :-( 247 String s = XMLTools.getNodeAsString( getRootElement(), PWMS + "Service/" + PWMS + "OnlineResource/@xlink:href", 248 nsContext, null ); 249 250 OnlineResource providerSite = null; 251 252 if ( s != null ) { 253 try { 254 providerSite = new OnlineResource( new Linkage( new URL( s ) ) ); 255 } catch ( MalformedURLException e ) { 256 throw new XMLParsingException( "could not parse service online resource", e ); 257 } 258 } else { 259 // use default if no online resource is contained in the 260 // capabilities (see comment above) 261 try { 262 providerSite = new OnlineResource( new Linkage( new URL( "http://www.opengeospatial.org/" ) ) ); 263 } catch ( MalformedURLException neverHappens ) { 264 // useless exception 265 } 266 } 267 268 String person = null; 269 String orga = null; 270 String position = null; 271 if ( ci != null ) { 272 person = XMLTools.getNodeAsString( ci, PWMS + "ContactPersonPrimary/" + PWMS + "ContactPerson", nsContext, 273 null ); 274 orga = XMLTools.getNodeAsString( ci, PWMS + "ContactPersonPrimary/" + PWMS + "ContactOrganization", 275 nsContext, null ); 276 position = XMLTools.getNodeAsString( ci, PWMS + "ContactPosition", nsContext, null ); 277 } 278 ContactInfo contact = parseContactInfo(); 279 280 CitedResponsibleParty party = new CitedResponsibleParty( new ContactInfo[] { contact }, 281 new String[] { person }, new String[] { orga }, 282 new String[] { position }, null ); 283 ServiceProvider sp = new ServiceProvider( person, providerSite, party ); 284 285 return sp; 286 } 287 288 /* 289 * Prefix added. 290 */ 291 @Override 292 protected ContactInfo parseContactInfo() 293 throws XMLParsingException { 294 Node ci = XMLTools.getNode( getRootElement(), PWMS + "Service/" + PWMS + "ContactInformation", nsContext ); 295 ContactInfo cont = null; 296 if ( ci != null ) { 297 String[] addr = XMLTools.getNodesAsStrings( ci, PWMS + "ContactAddress/" + PWMS + "Address", nsContext ); 298 // String addrType = 299 // XMLTools.getNodeAsString( ci, "./ContactAddress/AddressType", nsContext, null ); 300 String city = XMLTools.getNodeAsString( ci, PWMS + "ContactAddress/" + PWMS + "City", nsContext, null ); 301 String state = XMLTools.getNodeAsString( ci, PWMS + "ContactAddress/" + PWMS + "StateOrProvince", 302 nsContext, null ); 303 String pc = XMLTools.getNodeAsString( ci, PWMS + "ContactAddress/" + PWMS + "PostCode", nsContext, null ); 304 String country = XMLTools.getNodeAsString( ci, PWMS + "ContactAddress/" + PWMS + "Country", nsContext, null ); 305 String[] mail = XMLTools.getNodesAsStrings( ci, PWMS + "ContactElectronicMailAddress", nsContext ); 306 Address address = new Address( state, city, country, addr, mail, pc ); 307 308 String[] phone = XMLTools.getNodesAsStrings( ci, PWMS + "ContactVoiceTelephone", nsContext ); 309 String[] fax = XMLTools.getNodesAsStrings( ci, PWMS + "ContactFacsimileTelephone", nsContext ); 310 311 Phone ph = new Phone( fax, phone ); 312 313 cont = new ContactInfo( address, null, null, null, ph ); 314 } 315 316 return cont; 317 } 318 319 /* 320 * Prefix added. 321 */ 322 @Override 323 protected OperationsMetadata parseOperationsMetadata() 324 throws XMLParsingException { 325 326 Node opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PWMS 327 + "GetCapabilities", nsContext ); 328 329 if ( opNode == null ) { 330 // may it is a WMS 1.0.0 capabilities document 331 opNode = XMLTools.getRequiredNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PWMS 332 + "Capabilities", nsContext ); 333 } 334 Operation getCapa = parseOperation( opNode ); 335 336 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PWMS + "GetMap", 337 nsContext ); 338 if ( opNode == null ) { 339 // may it is a WMS 1.0.0 capabilities document 340 opNode = XMLTools.getRequiredNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PWMS 341 + "Map", nsContext ); 342 } 343 Operation getMap = parseOperation( opNode ); 344 345 opNode = XMLTools.getNode( getRootElement(), 346 PWMS + "Capability/" + PWMS + "Request/" + PWMS + "GetFeatureInfo", nsContext ); 347 Operation getFI = null; 348 if ( opNode != null ) { 349 getFI = parseOperation( opNode ); 350 } else { 351 // maybe its WMS 1.0.0 352 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PWMS 353 + "FeatureInfo", nsContext ); 354 if ( opNode != null ) { 355 getFI = parseOperation( opNode ); 356 } 357 } 358 359 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PSLD 360 + "GetLegendGraphic", nsContext ); 361 Operation getLG = null; 362 if ( opNode != null ) { 363 getLG = parseOperation( opNode ); 364 } 365 366 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PSLD + "DescribeLayer", 367 nsContext ); 368 Operation descL = null; 369 if ( opNode != null ) { 370 descL = parseOperation( opNode ); 371 } 372 373 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PSLD + "GetStyles", 374 nsContext ); 375 Operation getStyles = null; 376 if ( opNode != null ) { 377 getStyles = parseOperation( opNode ); 378 } 379 380 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PSLD + "PutStyles", 381 nsContext ); 382 Operation putStyles = null; 383 if ( opNode != null ) { 384 putStyles = parseOperation( opNode ); 385 } 386 387 List<Operation> operations = new ArrayList<Operation>(); 388 389 StringBuffer debug = new StringBuffer(); 390 391 if ( getCapa != null ) { 392 operations.add( getCapa ); 393 debug.append( " GetCapabilities" ); 394 } 395 if ( getMap != null ) { 396 operations.add( getMap ); 397 debug.append( " GetMap" ); 398 } 399 if ( getFI != null ) { 400 operations.add( getFI ); 401 debug.append( " GetFeatureInfo" ); 402 } 403 if ( getLG != null ) { 404 operations.add( getLG ); 405 debug.append( " GetLegendGraphic" ); 406 } 407 if ( descL != null ) { 408 operations.add( descL ); 409 debug.append( " DescribeLayer" ); 410 } 411 if ( getStyles != null ) { 412 operations.add( getStyles ); 413 debug.append( " GetStyles" ); 414 } 415 if ( putStyles != null ) { 416 operations.add( putStyles ); 417 debug.append( " PutStyles" ); 418 } 419 420 LOG.logDebug( "Configured request types:" + debug ); 421 422 OperationsMetadata metadata = new OperationsMetadata( null, null, operations, null ); 423 424 return metadata; 425 } 426 427 /* 428 * Prefix added. 429 */ 430 @Override 431 protected Operation parseOperation( Node node ) 432 throws XMLParsingException { 433 // use node name as name of the Operation to be defined 434 String name = node.getNodeName(); 435 if ( name.equals( "Capabilities" ) ) { 436 name = "GetCapabilities"; 437 } else if ( name.equals( "Map" ) ) { 438 name = "GetMap"; 439 } else if ( name.equals( "FeatureInfo" ) ) { 440 name = "GetFeatureInfo"; 441 } 442 443 String[] tmp = XMLTools.getRequiredNodesAsStrings( node, PWMS + "Format", nsContext ); 444 List<TypedLiteral> values = new ArrayList<TypedLiteral>(); 445 446 URI stringURI = null; 447 try { 448 stringURI = new URI( null, "String", null ); 449 } catch ( URISyntaxException e ) { 450 // cannot happen, why do I have to catch this? 451 } 452 453 for ( String str : tmp ) 454 values.add( new TypedLiteral( str, stringURI ) ); 455 456 DomainType owsDomainType = new DomainType( false, true, null, 0, new QualifiedName( "Format" ), values, null, 457 null, false, null, false, null, null, null, null ); 458 List<Parameter> parameters = new ArrayList<Parameter>(); 459 parameters.add( owsDomainType ); 460 461 List<?> nl = XMLTools.getRequiredNodes( node, PWMS + "DCPType", nsContext ); 462 List<DCP> dcps = new ArrayList<DCP>(); 463 464 for ( Object element : nl ) { 465 dcps.add( parseDCP( (Element) element ) ); 466 } 467 468 return new Operation( new QualifiedName( name ), dcps, parameters, null, null, null ); 469 } 470 471 /* 472 * Prefix added. 473 */ 474 @Override 475 protected DCP parseDCP( Element element ) 476 throws XMLParsingException { 477 List<HTTP.Type> types = new ArrayList<HTTP.Type>(); 478 List<OnlineResource> links = new ArrayList<OnlineResource>(); 479 480 Element elem = (Element) XMLTools.getRequiredNode( element, PWMS + "HTTP", nsContext ); 481 String s = null; 482 try { 483 List<?> nl = XMLTools.getNodes( elem, PWMS + "Get", nsContext ); 484 485 for ( int i = 0; i < nl.size(); i++ ) { 486 s = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@xlink:href", nsContext, null ); 487 if ( s == null ) { 488 s = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "OnlineResource/@xlink:href", 489 nsContext ); 490 } 491 types.add( HTTP.Type.Get ); 492 links.add( new OnlineResource( new Linkage( new URL( s ) ) ) ); 493 } 494 } catch ( Exception e ) { 495 throw new XMLParsingException( Messages.getMessage( "WMS_DCPGET", s ) ); 496 } 497 try { 498 List<?> nl = XMLTools.getNodes( elem, PWMS + "Post", nsContext ); 499 500 for ( int i = 0; i < nl.size(); i++ ) { 501 s = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@xlink:href", nsContext, null ); 502 if ( s == null ) { 503 s = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "OnlineResource/@xlink:href", 504 nsContext ); 505 } 506 types.add( HTTP.Type.Post ); 507 links.add( new OnlineResource( new Linkage( new URL( s ) ) ) ); 508 } 509 510 } catch ( MalformedURLException e ) { 511 throw new XMLParsingException( Messages.getMessage( "WMS_DCPPOST", s ) ); 512 } 513 HTTP http = new HTTP( links, null, types ); 514 515 return http; 516 } 517 518 /* 519 * Prefix added. Removed parsing of Extent. Removed parsing of ScaleHint. Changed SRS to CRS. 520 */ 521 @Override 522 protected Layer parseLayers( Element layerElem, Layer parent, ScaleHint scaleHint ) 523 throws XMLParsingException, UnknownCRSException { 524 525 boolean queryable = XMLTools.getNodeAsBoolean( layerElem, "./@queryable", nsContext, false ); 526 527 int cascaded = XMLTools.getNodeAsInt( layerElem, "./@cascaded", nsContext, 0 ); 528 boolean opaque = XMLTools.getNodeAsBoolean( layerElem, "./@opaque", nsContext, false ); 529 boolean noSubsets = XMLTools.getNodeAsBoolean( layerElem, "./@noSubsets", nsContext, false ); 530 int fixedWidth = XMLTools.getNodeAsInt( layerElem, "./@fixedWidth", nsContext, 0 ); 531 int fixedHeight = XMLTools.getNodeAsInt( layerElem, "./@fixedHeight", nsContext, 0 ); 532 String name = XMLTools.getNodeAsString( layerElem, PWMS + "Name", nsContext, null ); 533 String title = XMLTools.getRequiredNodeAsString( layerElem, PWMS + "Title", nsContext ); 534 String layerAbstract = XMLTools.getNodeAsString( layerElem, PWMS + "Abstract", nsContext, null ); 535 String[] keywords = XMLTools.getNodesAsStrings( layerElem, PWMS + "KeywordList/" + PWMS + "Keyword", nsContext ); 536 String[] srs = XMLTools.getNodesAsStrings( layerElem, PWMS + "CRS", nsContext ); 537 538 List<Element> nl = XMLTools.getElements( layerElem, PWMS + "BoundingBox", nsContext ); 539 // TODO 540 // substitue with Envelope 541 LayerBoundingBox[] bboxes = null; 542 if ( nl.size() == 0 && parent != null ) { 543 // inherit BoundingBoxes from parent layer 544 bboxes = parent.getBoundingBoxes(); 545 } else { 546 bboxes = parseLayerBoundingBoxes( nl ); 547 } 548 549 Element llBox = (Element) XMLTools.getNode( layerElem, PWMS + "EX_GeographicBoundingBox", nsContext ); 550 Envelope llBoundingBox = null; 551 552 if ( llBox == null && parent != null ) { 553 // inherit LatLonBoundingBox parent layer 554 llBoundingBox = parent.getLatLonBoundingBox(); 555 } else if ( llBox != null ) { 556 llBoundingBox = parseEX_GeographicBoundingBox( llBox ); 557 } else { 558 llBoundingBox = GeometryFactory.createEnvelope( -180, -90, 180, 90, CRSFactory.create( "EPSG:4326" ) ); 559 } 560 561 Dimension[] dimensions = parseDimensions( layerElem ); 562 563 Attribution attribution = parseAttribution( layerElem ); 564 565 AuthorityURL[] authorityURLs = parseAuthorityURLs( layerElem ); 566 567 MetadataURL[] metadataURLs = parseMetadataURLs( layerElem ); 568 569 DataURL[] dataURLs = parseDataURL( layerElem ); 570 571 Identifier[] identifiers = parseIdentifiers( layerElem ); 572 573 FeatureListURL[] featureListURLs = parseFeatureListURL( layerElem ); 574 575 Style[] styles = parseStyles( layerElem ); 576 577 scaleHint = parseScaleHint( layerElem, scaleHint ); 578 579 Layer layer = new Layer( queryable, cascaded, opaque, noSubsets, fixedWidth, fixedHeight, name, title, 580 layerAbstract, llBoundingBox, attribution, scaleHint, keywords, srs, bboxes, 581 dimensions, null, authorityURLs, identifiers, metadataURLs, dataURLs, featureListURLs, 582 styles, null, null, parent ); 583 584 // get Child layers 585 nl = XMLTools.getElements( layerElem, PWMS + "Layer", nsContext ); 586 Layer[] layers = new Layer[nl.size()]; 587 for ( int i = 0; i < layers.length; i++ ) { 588 layers[i] = parseLayers( nl.get( i ), layer, scaleHint ); 589 } 590 591 // set child layers 592 layer.setLayer( layers ); 593 594 return layer; 595 } 596 597 /* 598 * Prefix added. Changed to Min/MaxScaleDenominator. 599 */ 600 @Override 601 protected ScaleHint parseScaleHint( Element layerElem, ScaleHint scaleHint ) 602 throws XMLParsingException { 603 604 Node min = XMLTools.getNode( layerElem, PWMS + "MinScaleDenominator", nsContext ); 605 Node max = XMLTools.getNode( layerElem, PWMS + "MaxScaleDenominator", nsContext ); 606 if ( min != null ) { 607 double mn = XMLTools.getRequiredNodeAsDouble( min, ".", nsContext ); 608 double mx = XMLTools.getRequiredNodeAsDouble( max, ".", nsContext ); 609 scaleHint = new ScaleHint( mn, mx ); 610 } 611 612 if ( scaleHint == null ) { 613 scaleHint = new ScaleHint( 0, Double.MAX_VALUE ); 614 } 615 616 return scaleHint; 617 } 618 619 @Override 620 protected Dimension[] parseDimensions( Element layerElem ) 621 throws XMLParsingException { 622 List<Element> nl = getElements( layerElem, PWMS + "Dimension", nsContext ); 623 Dimension[] dimensions = new Dimension[nl.size()]; 624 625 for ( int i = 0; i < dimensions.length; i++ ) { 626 dimensions[i] = new Dimension( nl.get( i ) ); 627 } 628 629 return dimensions; 630 } 631 632 /* 633 * Prefix added. 634 */ 635 @Override 636 protected Attribution parseAttribution( Element layerElem ) 637 throws XMLParsingException { 638 639 Attribution attribution = null; 640 Node node = XMLTools.getNode( layerElem, PWMS + "Attribution", nsContext ); 641 if ( node != null ) { 642 String title = XMLTools.getRequiredNodeAsString( layerElem, PWMS + "Attribution/" + PWMS + "Title", 643 nsContext ); 644 OnlineResource onLineResource = parseOnLineResource( (Element) XMLTools.getRequiredNode( 645 node, 646 PWMS 647 + "OnlineResource", 648 nsContext ) ); 649 node = XMLTools.getNode( node, PWMS + "LogoURL", nsContext ); 650 LogoURL logoURL = null; 651 if ( node != null ) { 652 int width = XMLTools.getRequiredNodeAsInt( node, "./@width", nsContext ); 653 int height = XMLTools.getRequiredNodeAsInt( node, "./@height", nsContext ); 654 String format = XMLTools.getRequiredNodeAsString( node, "./Format", nsContext ); 655 OnlineResource logoOR = parseOnLineResource( (Element) XMLTools.getRequiredNode( 656 node, 657 PWMS 658 + "OnlineResource", 659 nsContext ) ); 660 logoURL = new LogoURL( width, height, format, logoOR.getLinkage().getHref() ); 661 } 662 attribution = new Attribution( title, onLineResource.getLinkage().getHref(), logoURL ); 663 } 664 665 return attribution; 666 } 667 668 /* 669 * Prefix added. 670 */ 671 @Override 672 protected AuthorityURL[] parseAuthorityURLs( Element layerElem ) 673 throws XMLParsingException { 674 675 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "AuthorityURL", nsContext ); 676 AuthorityURL[] authorityURLs = new AuthorityURL[nl.size()]; 677 for ( int i = 0; i < authorityURLs.length; i++ ) { 678 String name = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@name", nsContext ); 679 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), PWMS + "OnlineResource", nsContext ); 680 OnlineResource olr = parseOnLineResource( tmp ); 681 authorityURLs[i] = new AuthorityURL( name, olr.getLinkage().getHref() ); 682 } 683 684 return authorityURLs; 685 } 686 687 /* 688 * Prefix added. 689 */ 690 @Override 691 protected MetadataURL[] parseMetadataURLs( Element layerElem ) 692 throws XMLParsingException { 693 694 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "MetadataURL", nsContext ); 695 MetadataURL[] metadataURL = new MetadataURL[nl.size()]; 696 for ( int i = 0; i < metadataURL.length; i++ ) { 697 String type = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@type", nsContext ); 698 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "Format", nsContext ); 699 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), PWMS + "OnlineResource", nsContext ); 700 OnlineResource olr = parseOnLineResource( tmp ); 701 metadataURL[i] = new MetadataURL( type, format, olr.getLinkage().getHref() ); 702 703 } 704 705 return metadataURL; 706 } 707 708 /* 709 * Prefix added. 710 */ 711 @Override 712 protected DataURL[] parseDataURL( Element layerElem ) 713 throws XMLParsingException { 714 715 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "DataURL", nsContext ); 716 DataURL[] dataURL = new DataURL[nl.size()]; 717 for ( int i = 0; i < dataURL.length; i++ ) { 718 719 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "Format", nsContext ); 720 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), PWMS + "OnlineResource", nsContext ); 721 OnlineResource olr = parseOnLineResource( tmp ); 722 dataURL[i] = new DataURL( format, olr.getLinkage().getHref() ); 723 724 } 725 726 return dataURL; 727 } 728 729 /* 730 * Prefix added. 731 */ 732 @Override 733 protected FeatureListURL[] parseFeatureListURL( Element layerElem ) 734 throws XMLParsingException { 735 736 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "FeatureListURL", nsContext ); 737 FeatureListURL[] flURL = new FeatureListURL[nl.size()]; 738 for ( int i = 0; i < flURL.length; i++ ) { 739 740 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Format", nsContext ); 741 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), PWMS + "OnlineResource", nsContext ); 742 OnlineResource olr = parseOnLineResource( tmp ); 743 flURL[i] = new FeatureListURL( format, olr.getLinkage().getHref() ); 744 745 } 746 747 return flURL; 748 } 749 750 /* 751 * Prefix added. 752 */ 753 @Override 754 protected Style[] parseStyles( Element layerElem ) 755 throws XMLParsingException { 756 757 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "Style", nsContext ); 758 Style[] styles = new Style[nl.size()]; 759 for ( int i = 0; i < styles.length; i++ ) { 760 String name = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "Name", nsContext ); 761 762 if ( name == null ) { 763 throw new XMLParsingException( Messages.getMessage( "WMS_STYLENAME" ) ); 764 } 765 String title = XMLTools.getNodeAsString( (Node) nl.get( i ), PWMS + "Title", nsContext, null ); 766 if ( title == null ) { 767 throw new XMLParsingException( Messages.getMessage( "WMS_STYLETITLE" ) ); 768 } 769 String styleAbstract = XMLTools.getNodeAsString( (Node) nl.get( i ), PWMS + "Abstract", nsContext, null ); 770 LegendURL[] legendURLs = parseLegendURL( (Node) nl.get( i ) ); 771 StyleURL styleURL = parseStyleURL( (Node) nl.get( i ) ); 772 StyleSheetURL styleSheetURL = parseStyleSheetURL( (Node) nl.get( i ) ); 773 774 styles[i] = new Style( name, title, styleAbstract, legendURLs, styleSheetURL, styleURL, null ); 775 } 776 777 return styles; 778 } 779 780 /* 781 * Prefix added. 782 */ 783 @Override 784 protected LegendURL[] parseLegendURL( Node node ) 785 throws XMLParsingException { 786 787 List<?> nl = XMLTools.getNodes( node, PWMS + "LegendURL", nsContext ); 788 LegendURL[] lURL = new LegendURL[nl.size()]; 789 for ( int i = 0; i < lURL.length; i++ ) { 790 int width = XMLTools.getRequiredNodeAsInt( (Node) nl.get( i ), "./@width", nsContext ); 791 int height = XMLTools.getRequiredNodeAsInt( (Node) nl.get( i ), "./@height", nsContext ); 792 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "Format", nsContext ); 793 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), PWMS + "OnlineResource", nsContext ); 794 OnlineResource olr = parseOnLineResource( tmp ); 795 lURL[i] = new LegendURL( width, height, format, olr.getLinkage().getHref() ); 796 797 } 798 799 return lURL; 800 } 801 802 /* 803 * Prefix added. 804 */ 805 @Override 806 protected StyleURL parseStyleURL( Node node ) 807 throws XMLParsingException { 808 809 StyleURL styleURL = null; 810 Node styleNode = XMLTools.getNode( node, PWMS + "StyleURL", nsContext ); 811 812 if ( styleNode != null ) { 813 String format = XMLTools.getRequiredNodeAsString( styleNode, PWMS + "Format", nsContext ); 814 Element tmp = (Element) XMLTools.getRequiredNode( styleNode, PWMS + "OnlineResource", nsContext ); 815 OnlineResource olr = parseOnLineResource( tmp ); 816 styleURL = new StyleURL( format, olr.getLinkage().getHref() ); 817 818 } 819 820 return styleURL; 821 } 822 823 /* 824 * Prefix added. 825 */ 826 @Override 827 protected StyleSheetURL parseStyleSheetURL( Node node ) 828 throws XMLParsingException { 829 830 StyleSheetURL styleSheetURL = null; 831 Node styleNode = XMLTools.getNode( node, PWMS + "StyleSheetURL", nsContext ); 832 833 if ( styleNode != null ) { 834 String format = XMLTools.getRequiredNodeAsString( styleNode, PWMS + "Format", nsContext ); 835 Element tmp = (Element) XMLTools.getRequiredNode( styleNode, PWMS + "OnlineResource", nsContext ); 836 OnlineResource olr = parseOnLineResource( tmp ); 837 styleSheetURL = new StyleSheetURL( format, olr.getLinkage().getHref() ); 838 839 } 840 841 return styleSheetURL; 842 } 843 844 /* 845 * Prefix added. 846 */ 847 @Override 848 protected Identifier[] parseIdentifiers( Element layerElem ) 849 throws XMLParsingException { 850 851 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "Identifier", nsContext ); 852 Identifier[] identifiers = new Identifier[nl.size()]; 853 for ( int i = 0; i < identifiers.length; i++ ) { 854 String value = XMLTools.getStringValue( (Node) nl.get( i ) ); 855 String authority = XMLTools.getNodeAsString( layerElem, "./@authority", nsContext, null ); 856 identifiers[i] = new Identifier( value, authority ); 857 } 858 859 return identifiers; 860 } 861 862 /* 863 * Changed SRS to CRS. 864 */ 865 @Override 866 protected LayerBoundingBox[] parseLayerBoundingBoxes( List<Element> nl ) 867 throws XMLParsingException { 868 LayerBoundingBox[] llBoxes = new LayerBoundingBox[nl.size()]; 869 for ( int i = 0; i < llBoxes.length; i++ ) { 870 double minx = XMLTools.getRequiredNodeAsDouble( nl.get( i ), "./@minx", nsContext ); 871 double maxx = XMLTools.getRequiredNodeAsDouble( nl.get( i ), "./@maxx", nsContext ); 872 double miny = XMLTools.getRequiredNodeAsDouble( nl.get( i ), "./@miny", nsContext ); 873 double maxy = XMLTools.getRequiredNodeAsDouble( nl.get( i ), "./@maxy", nsContext ); 874 double resx = XMLTools.getNodeAsDouble( nl.get( i ), "./@resx", nsContext, -1 ); 875 double resy = XMLTools.getNodeAsDouble( nl.get( i ), "./@resx", nsContext, -1 ); 876 String srs = XMLTools.getRequiredNodeAsString( nl.get( i ), "./@CRS", nsContext ); 877 if ( srs.startsWith( "EPSG" ) ) { 878 Position min = GeometryFactory.createPosition( miny, minx ); 879 Position max = GeometryFactory.createPosition( maxy, maxx ); 880 llBoxes[i] = new LayerBoundingBox( min, max, srs, resx, resy ); 881 } else { 882 Position min = GeometryFactory.createPosition( minx, miny ); 883 Position max = GeometryFactory.createPosition( maxx, maxy ); 884 llBoxes[i] = new LayerBoundingBox( min, max, srs, resx, resy ); 885 } 886 } 887 888 return llBoxes; 889 } 890 891 /** 892 * 893 * @param llBox 894 * @return the envelope 895 * @throws XMLParsingException 896 * @throws UnknownCRSException 897 */ 898 protected Envelope parseEX_GeographicBoundingBox( Element llBox ) 899 throws XMLParsingException, UnknownCRSException { 900 901 double minx = XMLTools.getRequiredNodeAsDouble( llBox, PWMS + "westBoundLongitude", nsContext ); 902 double maxx = XMLTools.getRequiredNodeAsDouble( llBox, PWMS + "eastBoundLongitude", nsContext ); 903 double miny = XMLTools.getRequiredNodeAsDouble( llBox, PWMS + "southBoundLatitude", nsContext ); 904 double maxy = XMLTools.getRequiredNodeAsDouble( llBox, PWMS + "northBoundLatitude", nsContext ); 905 CoordinateSystem crs = CRSFactory.create( "EPSG:4326" ); 906 907 Envelope env = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, crs ); 908 909 return env; 910 } 911 912 }