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