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