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