001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/wpvs/capabilities/WPVSCapabilitiesDocument.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 037 package org.deegree.ogcwebservices.wpvs.capabilities; 038 039 import java.io.IOException; 040 import java.net.MalformedURLException; 041 import java.net.URI; 042 import java.net.URL; 043 import java.util.ArrayList; 044 import java.util.Arrays; 045 import java.util.HashMap; 046 import java.util.List; 047 import java.util.Map; 048 import java.util.Queue; 049 import java.util.concurrent.LinkedBlockingQueue; 050 051 import org.deegree.datatypes.values.TypedLiteral; 052 import org.deegree.datatypes.values.ValueRange; 053 import org.deegree.datatypes.xlink.SimpleLink; 054 import org.deegree.framework.log.ILogger; 055 import org.deegree.framework.log.LoggerFactory; 056 import org.deegree.framework.util.StringTools; 057 import org.deegree.framework.xml.NamespaceContext; 058 import org.deegree.framework.xml.XMLParsingException; 059 import org.deegree.framework.xml.XMLTools; 060 import org.deegree.i18n.Messages; 061 import org.deegree.model.crs.CRSFactory; 062 import org.deegree.model.crs.CoordinateSystem; 063 import org.deegree.model.crs.UnknownCRSException; 064 import org.deegree.model.metadata.iso19115.Keywords; 065 import org.deegree.model.metadata.iso19115.OnlineResource; 066 import org.deegree.model.spatialschema.Envelope; 067 import org.deegree.model.spatialschema.GeometryFactory; 068 import org.deegree.ogcbase.CommonNamespaces; 069 import org.deegree.ogcwebservices.InvalidParameterValueException; 070 import org.deegree.ogcwebservices.MissingParameterValueException; 071 import org.deegree.ogcwebservices.OGCWebServiceException; 072 import org.deegree.ogcwebservices.getcapabilities.DCPType; 073 import org.deegree.ogcwebservices.getcapabilities.HTTP; 074 import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException; 075 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities; 076 import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata; 077 import org.deegree.ogcwebservices.getcapabilities.Protocol; 078 import org.deegree.owscommon.OWSCommonCapabilitiesDocument; 079 import org.deegree.owscommon.OWSMetadata; 080 import org.deegree.owscommon.com110.HTTP110; 081 import org.deegree.owscommon.com110.OWSAllowedValues; 082 import org.deegree.owscommon.com110.OWSDomainType110; 083 import org.deegree.owscommon.com110.OWSRequestMethod; 084 import org.deegree.owscommon.com110.Operation110; 085 import org.w3c.dom.Element; 086 import org.w3c.dom.Node; 087 import org.xml.sax.SAXException; 088 089 /** 090 * This class represents a <code>WPVSCapabilitiesDocument</code> object. 091 * 092 * @author <a href="mailto:mays@lat-lon.de">Judit Mays</a> 093 * @author last edited by: $Author: mschneider $ 094 * 095 * $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 096 * 097 */ 098 public class WPVSCapabilitiesDocument extends OWSCommonCapabilitiesDocument { 099 100 private ArrayList<String> datasetIdentifiers = new ArrayList<String>(); 101 102 private ArrayList<String> styleIdentifiers = new ArrayList<String>(); 103 104 /** 105 * 106 */ 107 private static final long serialVersionUID = 2633513531080190745L; 108 109 private static final ILogger LOG = LoggerFactory.getLogger( WPVSCapabilitiesDocument.class ); 110 111 private static final String XML_TEMPLATE = "WPVSCapabilitiesTemplate.xml"; 112 113 private static String PRE_WPVS = CommonNamespaces.WPVS_PREFIX + ":"; 114 115 private static String PRE_OWS = CommonNamespaces.OWS_PREFIX + ":"; 116 117 /** 118 * Creates a skeleton capabilities document that contains the mandatory elements only. 119 * 120 * @throws IOException 121 * @throws SAXException 122 */ 123 public void createEmptyDocument() 124 throws IOException, SAXException { 125 URL url = WPVSCapabilitiesDocument.class.getResource( XML_TEMPLATE ); 126 if ( url == null ) { 127 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." ); 128 } 129 load( url ); 130 } 131 132 /** 133 * @see org.deegree.ogcwebservices.getcapabilities.OGCCapabilitiesDocument#parseCapabilities() 134 */ 135 @Override 136 public OGCCapabilities parseCapabilities() 137 throws InvalidCapabilitiesException { 138 WPVSCapabilities wpvsCapabilities = null; 139 140 try { 141 wpvsCapabilities = new WPVSCapabilities( parseVersion(), 142 parseUpdateSequence(), 143 getServiceIdentification(), 144 getServiceProvider(), 145 parseOperationsMetadata( null ), 146 null, 147 getDataset() ); 148 149 } catch ( XMLParsingException e ) { 150 throw new InvalidCapabilitiesException( e.getMessage() + "\n" + StringTools.stackTraceToString( e ) ); 151 152 } catch ( MissingParameterValueException e ) { 153 throw new InvalidCapabilitiesException( e.getMessage() + "\n" + StringTools.stackTraceToString( e ) ); 154 155 } catch ( InvalidParameterValueException e ) { 156 throw new InvalidCapabilitiesException( e.getMessage() + "\n" + StringTools.stackTraceToString( e ) ); 157 158 } catch ( OGCWebServiceException e ) { 159 throw new InvalidCapabilitiesException( e.getMessage() + "\n" + StringTools.stackTraceToString( e ) ); 160 } 161 162 return wpvsCapabilities; 163 } 164 165 /** 166 * Gets the <code>Dataset</code> object from the root element of the WPVSCapabilities element. 167 * 168 * 169 * @return Returns the Dataset object form root element. 170 * @throws XMLParsingException 171 * @throws OGCWebServiceException 172 * @throws InvalidParameterValueException 173 * @throws MissingParameterValueException 174 */ 175 private Dataset getDataset() 176 throws XMLParsingException, MissingParameterValueException, 177 InvalidParameterValueException, OGCWebServiceException { 178 179 Element datasetElement = (Element) XMLTools.getRequiredNode( getRootElement(), PRE_WPVS + "Dataset", nsContext ); 180 Dataset dataset = parseDataset( datasetElement, null, null, null ); 181 182 return dataset; 183 } 184 185 /** 186 * Creates and returns a new <code>Dataset</code> object from the given <code>Element</code> and the parent 187 * <code>Dataset</code> object. 188 * 189 * @param datasetElement 190 * @param parent 191 * may be null if root node 192 * @param defaultCoordinateSystem 193 * @param defaultElevationModel 194 * @return Returns a new Dataset object. 195 * @throws XMLParsingException 196 * @throws OGCWebServiceException 197 * @throws InvalidParameterValueException 198 */ 199 private Dataset parseDataset( Element datasetElement, Dataset parent, CoordinateSystem defaultCoordinateSystem, 200 ElevationModel defaultElevationModel ) 201 throws XMLParsingException, 202 InvalidParameterValueException, 203 OGCWebServiceException { 204 205 // attributes are all optional 206 boolean queryable = XMLTools.getNodeAsBoolean( datasetElement, "@queryable", nsContext, false ); 207 boolean opaque = XMLTools.getNodeAsBoolean( datasetElement, "@opaque", nsContext, false ); 208 boolean noSubsets = XMLTools.getNodeAsBoolean( datasetElement, "@noSubsets", nsContext, false ); 209 int fixedWidth = XMLTools.getNodeAsInt( datasetElement, "@fixedWidth", nsContext, 0 ); 210 int fixedHeight = XMLTools.getNodeAsInt( datasetElement, "@fixedHeight", nsContext, 0 ); 211 212 // elements 213 String name = XMLTools.getNodeAsString( datasetElement, PRE_WPVS + "Name/text()", nsContext, null ); 214 String title = XMLTools.getRequiredNodeAsString( datasetElement, PRE_WPVS + "Title/text()", nsContext ); 215 String abstract_ = XMLTools.getNodeAsString( datasetElement, PRE_WPVS + "Abstract/text()", nsContext, null ); 216 // keywords == optional 217 Keywords[] keywords = getKeywords( XMLTools.getNodes( datasetElement, PRE_OWS + "Keywords", nsContext ) ); 218 // crsstrings == optional 219 String[] crsStrings = XMLTools.getNodesAsStrings( datasetElement, PRE_WPVS + "CRS/text()", nsContext ); 220 List<CoordinateSystem> crsList = parseCoordinateSystems( crsStrings ); 221 ElevationModel elevationModel = parseElevationModel( datasetElement, defaultElevationModel ); 222 // create a default ElevationModel if not exists allready, a little HACK to circumvent the 223 // optional deegree:dataset:ElevationModel mapping onto the mandatory 224 // ogc:dataset:ElevationModel 225 if ( defaultElevationModel == null && elevationModel != null ) { 226 defaultElevationModel = elevationModel; 227 // found an ElevationModel setting it to default 228 // and update the parents of this dataset, until we have the root, 229 230 if ( parent != null ) { 231 // first find root parent 232 Dataset tmpParent = parent; 233 while ( tmpParent.getParent() != null ) { 234 tmpParent = tmpParent.getParent(); 235 } 236 // now iterate over all so far created children to set an default elevationmodel 237 tmpParent.setElevationModel( defaultElevationModel ); 238 Queue<Dataset> children = new LinkedBlockingQueue<Dataset>( Arrays.asList( tmpParent.getDatasets() ) ); 239 while ( !children.isEmpty() ) { 240 Dataset child = children.poll(); 241 if ( child != null ) { 242 child.setElevationModel( defaultElevationModel ); 243 for ( Dataset dataset : child.getDatasets() ) { 244 children.offer( dataset ); 245 } 246 } 247 } 248 } 249 } 250 // now find a defaultcoordinatesystem to use if no crs is given in a child dataset 251 if ( parent == null ) { // root dataset 252 if ( crsList.size() == 0 || crsList.get( 0 ) == null ) { 253 throw new InvalidCapabilitiesException( Messages.getMessage( "WPVS_NO_TOPLEVEL_DATASET_CRS", title ) ); 254 } 255 defaultCoordinateSystem = crsList.get( 0 ); 256 } 257 258 String[] format = XMLTools.getRequiredNodesAsStrings( datasetElement, PRE_WPVS + "Format/text()", nsContext ); 259 // wgs84 == mandatory 260 Element boundingBoxElement = (Element) XMLTools.getRequiredNode( datasetElement, 261 PRE_OWS + "WGS84BoundingBox", 262 nsContext ); 263 Envelope wgs84BoundingBox = getWGS84BoundingBoxType( boundingBoxElement ); 264 265 // boundingboxes can be used to make a more precise specification of the useable area of 266 // this dataset in it's native crs's, the wgs84 bbox can be inaccurate 267 Envelope[] boundingBoxes = getBoundingBoxes( datasetElement, defaultCoordinateSystem ); 268 269 // optional 270 Dimension[] dimensions = parseDimensions( datasetElement ); 271 272 // optional 273 DataProvider dataProvider = parseDataProvider( datasetElement ); 274 275 // mandatory 276 Identifier identifier = parseDatasetIdentifier( datasetElement, PRE_WPVS + "Identifier" ); 277 278 // optional 279 MetaData[] metaData = parseMetaData( datasetElement ); 280 281 // optional 282 DatasetReference[] datasetRefs = parseDatasetReferences( datasetElement ); 283 284 // optional 285 FeatureListReference[] featureListRefs = parseFeatureListReferences( datasetElement ); 286 287 // optional 288 Style[] style = parseStyles( datasetElement ); 289 290 // mandatory 291 double minScaleDenom = XMLTools.getRequiredNodeAsDouble( datasetElement, 292 PRE_WPVS + "MinimumScaleDenominator/text()", 293 nsContext ); 294 // mandatory 295 double maxScaleDenom = XMLTools.getRequiredNodeAsDouble( datasetElement, 296 PRE_WPVS + "MaximumScaleDenominator/text()", 297 nsContext ); 298 299 if ( minScaleDenom > maxScaleDenom ) { 300 throw new InvalidCapabilitiesException( Messages.getMessage( "WPVS_WRONG_SCALE_DENOMINATORS" ) ); 301 } 302 303 // create new root dataset 304 Dataset dataset = new Dataset( queryable, 305 opaque, 306 noSubsets, 307 fixedWidth, 308 fixedHeight, 309 name, 310 title, 311 abstract_, 312 keywords, 313 crsList, 314 format, 315 wgs84BoundingBox, 316 boundingBoxes, 317 dimensions, 318 dataProvider, 319 identifier, 320 metaData, 321 datasetRefs, 322 featureListRefs, 323 style, 324 minScaleDenom, 325 maxScaleDenom, 326 null, 327 elevationModel, 328 null, 329 parent ); 330 331 // get child datasets 332 List<Node> nl = XMLTools.getNodes( datasetElement, PRE_WPVS + "Dataset", nsContext ); 333 Dataset[] childDatasets = new Dataset[nl.size()]; 334 for ( int i = 0; i < childDatasets.length; i++ ) { 335 childDatasets[i] = parseDataset( (Element) nl.get( i ), 336 dataset, 337 defaultCoordinateSystem, 338 defaultElevationModel ); 339 } 340 341 // set child datasets 342 dataset.setDatasets( childDatasets ); 343 344 return dataset; 345 } 346 347 /** 348 * @param coordinateStrings 349 * the Strings to create the coordinates from 350 * @return a List of coordinatesystems, if no coordinateString were given (null || length==0 ) an emtpy list is 351 * returned. 352 */ 353 protected List<CoordinateSystem> parseCoordinateSystems( String[] coordinateStrings ) { 354 if ( coordinateStrings == null ) 355 return new ArrayList<CoordinateSystem>(); 356 ArrayList<CoordinateSystem> crsList = new ArrayList<CoordinateSystem>( coordinateStrings.length ); 357 for ( String tmpCRS : coordinateStrings ) { 358 try { 359 CoordinateSystem crs = CRSFactory.create( tmpCRS ); 360 crsList.add( crs ); 361 } catch ( UnknownCRSException e ) { 362 // fail configuration notify the user 363 LOG.logError( e.getLocalizedMessage(), e ); 364 } 365 } 366 return crsList; 367 } 368 369 /** 370 * Creates and returns a new <code>ElevationModel</code> object from the given <code>Element</code>. 371 * 372 * This OGC ElevationModel contains only a String. ATTENTION ogc elevation model is mandatory, we IGNORE this and 373 * say it's mandatory. 374 * 375 * @param datasetElement 376 * @param defaultElevationModel 377 * the defaultElevationModel will be used if no elevationmodel was defined in this dataset(for example 378 * the topdatasets dgm-name) 379 * @return Returns the ElevationModel object or <code>null</code> if none defined (optional) 380 * @throws XMLParsingException 381 */ 382 private ElevationModel parseElevationModel( Element datasetElement, ElevationModel defaultElevationModel ) 383 throws XMLParsingException { 384 // ATTENTION ogc elevation model is mandatory, we IGNORE it for the capabilities. 385 String name = XMLTools.getNodeAsString( datasetElement, PRE_WPVS + "ElevationModel/text()", nsContext, null ); 386 if ( name == null ) { 387 if ( defaultElevationModel == null ) { 388 return null; 389 } 390 return defaultElevationModel; 391 } 392 ElevationModel elevationModel = new ElevationModel( name ); 393 394 return elevationModel; 395 } 396 397 /** 398 * Creates and returns a new array of <code>Style</code> objects from the given <code>Element</code>. 399 * 400 * @param datasetElement 401 * @return Returns a new array of Style objects or <code>null</code> if none were defined 402 * @throws XMLParsingException 403 * @throws InvalidCapabilitiesException 404 */ 405 protected Style[] parseStyles( Element datasetElement ) 406 throws XMLParsingException, InvalidCapabilitiesException { 407 408 List<Node> styleList = XMLTools.getNodes( datasetElement, PRE_WPVS + "Style", nsContext ); 409 // optional therefore return null if not present 410 if ( styleList.size() == 0 ) { 411 return null; 412 } 413 414 Style[] styles = new Style[styleList.size()]; 415 416 for ( int i = 0; i < styles.length; i++ ) { 417 418 Element styleElement = (Element) styleList.get( i ); 419 420 String name = XMLTools.getRequiredNodeAsString( styleElement, PRE_WPVS + "Name/text()", nsContext ); 421 String title = XMLTools.getRequiredNodeAsString( styleElement, PRE_WPVS + "Title/text()", nsContext ); 422 String abstract_ = XMLTools.getRequiredNodeAsString( styleElement, PRE_WPVS + "Abstract/text()", nsContext ); 423 // optional 424 Keywords[] keywords = getKeywords( XMLTools.getNodes( styleElement, PRE_OWS + "Keywords", nsContext ) ); 425 // mandatory 426 Identifier identifier = parseStyleIdentifier( styleElement, PRE_WPVS + "Identifier" ); 427 428 // optional 429 LegendURL[] legendURLs = parseLegendURLs( styleElement ); 430 431 // optional 432 StyleSheetURL styleSheetURL = parseStyleSheetURL( styleElement ); 433 StyleURL styleURL = parseStyleURL( styleElement ); 434 435 styles[i] = new Style( name, title, abstract_, keywords, identifier, legendURLs, styleSheetURL, styleURL ); 436 } 437 438 return styles; 439 } 440 441 /** 442 * Creates and returns a new <code>StyleURL</code> object from the given <code>Element</code>. 443 * 444 * @param styleElement 445 * @return Returns a new StyleURL object or <code>null</code> if not defined (optional) 446 * @throws XMLParsingException 447 * @throws InvalidCapabilitiesException 448 */ 449 private StyleURL parseStyleURL( Element styleElement ) 450 throws XMLParsingException, InvalidCapabilitiesException { 451 452 Element styleURLElement = (Element) XMLTools.getNode( styleElement, PRE_WPVS + "StyleURL", nsContext ); 453 if ( styleURLElement == null ) { 454 return null; 455 } 456 String format = XMLTools.getRequiredNodeAsString( styleURLElement, PRE_WPVS + "Format/text()", nsContext ); 457 458 // optional 459 URI onlineResourceURI = XMLTools.getNodeAsURI( styleURLElement, 460 PRE_WPVS + "OnlineResource/@xlink:href", 461 nsContext, 462 null ); 463 URL onlineResource = null; 464 if ( onlineResourceURI != null ) { 465 try { 466 onlineResource = onlineResourceURI.toURL(); 467 } catch ( MalformedURLException e ) { 468 throw new InvalidCapabilitiesException( onlineResourceURI + " does not represent a valid URL: " 469 + e.getMessage() ); 470 } 471 } 472 return new StyleURL( format, onlineResource ); 473 } 474 475 /** 476 * Creates and returns a new <code>StyleSheetURL</code> object from the given <code>Element</code>. 477 * 478 * @param styleElement 479 * @return Returns a new StyleSheetURL object or <code>null</code> if no stylSheetURL was given (optional) 480 * @throws XMLParsingException 481 * @throws InvalidCapabilitiesException 482 */ 483 private StyleSheetURL parseStyleSheetURL( Element styleElement ) 484 throws XMLParsingException, 485 InvalidCapabilitiesException { 486 487 Element styleSheetURLElement = (Element) XMLTools.getNode( styleElement, PRE_WPVS + "StyleSheetURL", nsContext ); 488 if ( styleSheetURLElement == null ) { 489 return null; 490 } 491 String format = XMLTools.getRequiredNodeAsString( styleSheetURLElement, PRE_WPVS + "Format/text()", nsContext ); 492 493 // optional onlineResource 494 URI onlineResourceURI = XMLTools.getNodeAsURI( styleSheetURLElement, 495 PRE_WPVS + "OnlineResource/@xlink:href", 496 nsContext, 497 null ); 498 URL onlineResource = null; 499 if ( onlineResourceURI != null ) { 500 try { 501 onlineResource = onlineResourceURI.toURL(); 502 } catch ( MalformedURLException e ) { 503 throw new InvalidCapabilitiesException( onlineResourceURI + " does not represent a valid URL: " 504 + e.getMessage() ); 505 } 506 } 507 508 return new StyleSheetURL( format, onlineResource ); 509 } 510 511 /** 512 * Creates and returns a new array of <code>LegendURL</code> objects from the given <code>Element</code>. 513 * 514 * @param styleElement 515 * @return Returns a new array of LegendURL objects or <code>null</code> if none were defined (optional). 516 * @throws XMLParsingException 517 * @throws InvalidCapabilitiesException 518 */ 519 private LegendURL[] parseLegendURLs( Element styleElement ) 520 throws XMLParsingException, InvalidCapabilitiesException { 521 522 List<Node> legendList = XMLTools.getNodes( styleElement, PRE_WPVS + "LegendURL", nsContext ); 523 if ( legendList.size() == 0 ) { 524 return null; 525 } 526 527 LegendURL[] legendURLs = new LegendURL[legendList.size()]; 528 529 for ( int i = 0; i < legendURLs.length; i++ ) { 530 531 Element legendURLElement = (Element) legendList.get( i ); 532 533 int width = XMLTools.getRequiredNodeAsInt( legendURLElement, "@width", nsContext ); 534 int height = XMLTools.getRequiredNodeAsInt( legendURLElement, "@height", nsContext ); 535 if ( width < 0 || height < 0 ) { 536 throw new InvalidCapabilitiesException( "The attributes width and height of '" + legendURLElement.getNodeName() 537 + "' must be positive!" ); 538 } 539 540 String format = XMLTools.getRequiredNodeAsString( legendURLElement, PRE_WPVS + "Format/text()", nsContext ); 541 // optional 542 URI onlineResourceURI = XMLTools.getNodeAsURI( legendURLElement, 543 PRE_WPVS + "OnlineResource/@xlink:href", 544 nsContext, 545 null ); 546 547 URL onlineResource = null; 548 if ( onlineResourceURI != null ) { 549 try { 550 onlineResource = onlineResourceURI.toURL(); 551 } catch ( MalformedURLException e ) { 552 throw new InvalidCapabilitiesException( onlineResourceURI + " does not represent a valid URL: " 553 + e.getMessage() ); 554 } 555 } 556 557 legendURLs[i] = new LegendURL( width, height, format, onlineResource ); 558 } 559 return legendURLs; 560 } 561 562 /** 563 * Creates and returns a new array of <code>FeatureListReference</code> objects from the given 564 * <code>Element</code>. 565 * 566 * @param datasetElement 567 * @return Returns an array of FeatureListReference instances or <code>null</code> if none were defined 568 * (optional). 569 * @throws XMLParsingException 570 * @throws InvalidCapabilitiesException 571 */ 572 protected FeatureListReference[] parseFeatureListReferences( Element datasetElement ) 573 throws XMLParsingException, 574 InvalidCapabilitiesException { 575 576 List<Node> featureList = XMLTools.getNodes( datasetElement, PRE_WPVS + "FeatureListReference", nsContext ); 577 if ( featureList.size() == 0 ) { 578 return null; 579 } 580 FeatureListReference[] featureRefs = new FeatureListReference[featureList.size()]; 581 for ( int i = 0; i < featureRefs.length; i++ ) { 582 583 Element featureRefElement = (Element) featureList.get( i ); 584 585 String format = XMLTools.getRequiredNodeAsString( featureRefElement, PRE_WPVS + "Format/text()", nsContext ); 586 587 URI onlineResourceURI = XMLTools.getNodeAsURI( featureRefElement, 588 PRE_WPVS + "OnlineResource/@xlink:href", 589 nsContext, 590 null ); 591 URL onlineResource = null; 592 if ( onlineResourceURI != null ) { 593 try { 594 onlineResource = onlineResourceURI.toURL(); 595 } catch ( MalformedURLException e ) { 596 throw new InvalidCapabilitiesException( onlineResourceURI + " does not represent a valid URL: " 597 + e.getMessage() ); 598 } 599 } 600 featureRefs[i] = new FeatureListReference( format, onlineResource ); 601 } 602 return featureRefs; 603 } 604 605 /** 606 * Creates and returns a new array of <code>DatasetReference</code> objects from the given <code>Element</code>. 607 * 608 * @param datasetElement 609 * @return Returns a new array of DatasetReference objects or <code>null</code> if no DatasetReferences are 610 * specified in this dataset (optional) 611 * @throws XMLParsingException 612 * @throws InvalidCapabilitiesException 613 */ 614 protected DatasetReference[] parseDatasetReferences( Element datasetElement ) 615 throws XMLParsingException, 616 InvalidCapabilitiesException { 617 618 List<Node> datasetRefList = XMLTools.getNodes( datasetElement, PRE_WPVS + "DatasetReference", nsContext ); 619 if ( datasetRefList == null ) { 620 return null; 621 } 622 DatasetReference[] datasetRefs = new DatasetReference[datasetRefList.size()]; 623 624 for ( int i = 0; i < datasetRefs.length; i++ ) { 625 626 Element datasetRefElement = (Element) datasetRefList.get( i ); 627 628 String format = XMLTools.getRequiredNodeAsString( datasetRefElement, PRE_WPVS + "Format/text()", nsContext ); 629 630 URI onlineResourceURI = XMLTools.getNodeAsURI( datasetRefElement, 631 PRE_WPVS + "OnlineResource/@xlink:href", 632 nsContext, 633 null ); 634 URL onlineResource = null; 635 if ( onlineResourceURI != null ) { 636 try { 637 onlineResource = onlineResourceURI.toURL(); 638 } catch ( MalformedURLException e ) { 639 throw new InvalidCapabilitiesException( onlineResourceURI + " does not represent a valid URL: " 640 + e.getMessage() ); 641 } 642 } 643 datasetRefs[i] = new DatasetReference( format, onlineResource ); 644 } 645 646 return datasetRefs; 647 } 648 649 /** 650 * Creates and returns a new <code>MetaData</code> object from the given <code>Element</code>. 651 * 652 * @param datasetElement 653 * @return Returns an array of MetaData objects, or <code>null</code> if no metadata was specified in the dataset 654 * (optional). 655 * @throws XMLParsingException 656 * @throws InvalidCapabilitiesException 657 */ 658 protected MetaData[] parseMetaData( Element datasetElement ) 659 throws XMLParsingException, 660 InvalidCapabilitiesException { 661 662 List<Node> metaDataList = XMLTools.getNodes( datasetElement, PRE_WPVS + "MetaData", nsContext ); 663 if ( metaDataList.size() == 0 ) { 664 return null; 665 } 666 MetaData[] metaData = new MetaData[metaDataList.size()]; 667 668 for ( int i = 0; i < metaData.length; i++ ) { 669 670 Element metaDataElement = (Element) metaDataList.get( i ); 671 672 String type = XMLTools.getRequiredNodeAsString( metaDataElement, "@type", nsContext ); 673 674 String format = XMLTools.getRequiredNodeAsString( metaDataElement, PRE_WPVS + "Format/text()", nsContext ); 675 URI onlineResourceURI = XMLTools.getNodeAsURI( metaDataElement, 676 PRE_WPVS + "OnlineResource/@xlink:href", 677 nsContext, 678 null ); 679 URL onlineResource = null; 680 if ( onlineResourceURI != null ) { 681 try { 682 onlineResource = onlineResourceURI.toURL(); 683 } catch ( MalformedURLException e ) { 684 throw new InvalidCapabilitiesException( onlineResourceURI + " does not represent a valid URL: " 685 + e.getMessage() ); 686 } 687 } 688 689 metaData[i] = new MetaData( type, format, onlineResource ); 690 } 691 692 return metaData; 693 } 694 695 /** 696 * Creates and returns a new <code>Identifier</code> object from the given <code>Element</code> and the given 697 * <cod>xPathQuery</code>. 698 * 699 * @param element 700 * @param xPathQuery 701 * @return Returns a new Identifier object. 702 * @throws XMLParsingException 703 * @throws InvalidCapabilitiesException 704 * if no (valid) identifier is found 705 */ 706 protected Identifier parseStyleIdentifier( Element element, String xPathQuery ) 707 throws XMLParsingException, 708 InvalidCapabilitiesException { 709 710 Element identifierElement = (Element) XMLTools.getRequiredNode( element, xPathQuery, nsContext ); 711 712 String value = XMLTools.getStringValue( identifierElement ).trim(); 713 if ( "".equals( value ) ) { 714 throw new InvalidCapabilitiesException( Messages.getMessage( "WPVS_NO_VALID_IDENTIFIER", "style" ) ); 715 } 716 URI codeSpace = XMLTools.getNodeAsURI( identifierElement, "@codeSpace", nsContext, null ); 717 718 Identifier id = new Identifier( value, codeSpace ); 719 if ( styleIdentifiers.contains( id.toString() ) ) { 720 throw new InvalidCapabilitiesException( Messages.getMessage( "WPVS_NO_UNIQUE_IDENTIFIER", 721 "styles", 722 id.toString() ) ); 723 724 } 725 styleIdentifiers.add( id.toString() ); 726 return id; 727 } 728 729 /** 730 * Creates and returns a new <code>Identifier</code> object from the given <code>Element</code> and the given 731 * <cod>xPathQuery</code>. 732 * 733 * @param element 734 * @param xPathQuery 735 * @return Returns a new Identifier object. 736 * @throws XMLParsingException 737 * @throws InvalidCapabilitiesException 738 * if no (valid) identifier is found 739 */ 740 protected Identifier parseDatasetIdentifier( Element element, String xPathQuery ) 741 throws XMLParsingException, 742 InvalidCapabilitiesException { 743 744 Element identifierElement = (Element) XMLTools.getRequiredNode( element, xPathQuery, nsContext ); 745 746 String value = XMLTools.getStringValue( identifierElement ).trim(); 747 if ( "".equals( value ) ) { 748 throw new InvalidCapabilitiesException( Messages.getMessage( "WPVS_NO_VALID_IDENTIFIER", "dataset" ) ); 749 } 750 URI codeSpace = XMLTools.getNodeAsURI( identifierElement, "@codeSpace", nsContext, null ); 751 Identifier id = new Identifier( value, codeSpace ); 752 if ( datasetIdentifiers.contains( id.toString() ) ) { 753 throw new InvalidCapabilitiesException( Messages.getMessage( "WPVS_NO_UNIQUE_IDENTIFIER", 754 "datasets", 755 id.toString() ) ); 756 757 } 758 datasetIdentifiers.add( id.toString() ); 759 760 return id; 761 } 762 763 /** 764 * Creates and returns a new <code>DataProvider</code> object from the given <code>Element</code>. 765 * 766 * @param datasetElement 767 * @return Returns a new DataProvider object or <code>null</code>if no provider was defined. 768 * @throws XMLParsingException 769 * @throws InvalidCapabilitiesException 770 */ 771 protected DataProvider parseDataProvider( Element datasetElement ) 772 throws XMLParsingException, 773 InvalidCapabilitiesException { 774 775 String providerName = null; 776 URL providerSite = null; 777 LogoURL logoURL = null; 778 779 Element dataProviderElement = (Element) XMLTools.getNode( datasetElement, PRE_WPVS + "DataProvider", nsContext ); 780 if ( dataProviderElement == null ) 781 return null; 782 783 providerName = XMLTools.getNodeAsString( dataProviderElement, PRE_WPVS + "ProviderName/text()", nsContext, null ); 784 URI providerSiteURI = XMLTools.getNodeAsURI( dataProviderElement, 785 PRE_WPVS + "ProviderSite/@xlink:href", 786 nsContext, 787 null ); 788 if ( providerSiteURI != null ) { 789 try { 790 providerSite = providerSiteURI.toURL(); 791 } catch ( MalformedURLException e ) { 792 throw new InvalidCapabilitiesException( providerSiteURI + " does not represent a valid URL: " 793 + e.getMessage() ); 794 } 795 } 796 797 Node logoURLElement = XMLTools.getNode( dataProviderElement, PRE_WPVS + "LogoURL", nsContext ); 798 if ( logoURLElement != null ) { 799 800 int width = XMLTools.getRequiredNodeAsInt( logoURLElement, "@width", nsContext ); 801 int height = XMLTools.getRequiredNodeAsInt( logoURLElement, "@height", nsContext ); 802 if ( width < 0 || height < 0 ) { 803 throw new InvalidCapabilitiesException( "width and height of '" + logoURLElement 804 + "' must be positive!" ); 805 } 806 807 String format = XMLTools.getRequiredNodeAsString( logoURLElement, PRE_WPVS + "Format/text()", nsContext ); 808 809 URI onlineResourceURI = XMLTools.getNodeAsURI( logoURLElement, 810 PRE_WPVS + "OnlineResource/@xlink:href", 811 nsContext, 812 null ); 813 URL onlineResource = null; 814 if ( onlineResourceURI != null ) { 815 try { 816 onlineResource = onlineResourceURI.toURL(); 817 } catch ( MalformedURLException e ) { 818 throw new InvalidCapabilitiesException( onlineResourceURI + " does not represent a valid URL: " 819 + e.getMessage() ); 820 } 821 } 822 823 logoURL = new LogoURL( width, height, format, onlineResource ); 824 } 825 return new DataProvider( providerName, providerSite, logoURL ); 826 } 827 828 /** 829 * 830 * @param element 831 * @return the Dimensions of a given element or <code>null</code> if no dimension is found (optional). 832 * @throws XMLParsingException 833 */ 834 protected Dimension[] parseDimensions( Element element ) 835 throws XMLParsingException { 836 837 List<Node> nl = XMLTools.getNodes( element, PRE_WPVS + "Dimension", nsContext ); 838 if ( nl.size() == 0 ) { 839 return null; 840 } 841 Dimension[] dimensions = new Dimension[nl.size()]; 842 843 for ( int i = 0; i < dimensions.length; i++ ) { 844 Node dimNode = nl.get( i ); 845 String name = XMLTools.getRequiredNodeAsString( dimNode, "@name", nsContext ); 846 String units = XMLTools.getRequiredNodeAsString( dimNode, "@units", nsContext ); 847 String unitSymbol = XMLTools.getNodeAsString( dimNode, "@unitSymbol", nsContext, null ); 848 String default_ = XMLTools.getNodeAsString( dimNode, "@default", nsContext, null ); 849 Boolean multipleValues = Boolean.valueOf( XMLTools.getNodeAsBoolean( dimNode, 850 "@multipleValues", 851 nsContext, 852 true ) ); 853 Boolean nearestValues = Boolean.valueOf( XMLTools.getNodeAsBoolean( dimNode, 854 "@nearestValues", 855 nsContext, 856 true ) ); 857 Boolean current = Boolean.valueOf( XMLTools.getNodeAsBoolean( dimNode, 858 "@current", 859 nsContext, 860 true ) ); 861 String value = XMLTools.getNodeAsString( dimNode, ".", nsContext, null ); 862 863 dimensions[i] = new Dimension( name, 864 units, 865 unitSymbol, 866 default_, 867 multipleValues, 868 nearestValues, 869 current, 870 value ); 871 } 872 873 return dimensions; 874 } 875 876 /** 877 * Gets an array of <code>boundingBoxes</code> from the given <code>Element</code>. This method returns all 878 * boundingBoxes together in one array. 879 * 880 * @param element 881 * @param defaultCoordinateSystem 882 * to be used for not defined coordinate system attribute in the bbox element 883 * @return Returns an array of boundingBoxes. 884 * @throws XMLParsingException 885 * @throws InvalidParameterValueException 886 */ 887 protected Envelope[] getBoundingBoxes( Element element, CoordinateSystem defaultCoordinateSystem ) 888 throws XMLParsingException, 889 InvalidParameterValueException { 890 891 List<Node> boundingBoxList = XMLTools.getNodes( element, PRE_OWS + "BoundingBox", nsContext ); 892 893 List<Envelope> bboxesList = new ArrayList<Envelope>( boundingBoxList.size() ); 894 895 for ( int i = 0; i < boundingBoxList.size(); i++ ) { 896 bboxesList.add( parseBoundingBox( (Element) boundingBoxList.get( i ), defaultCoordinateSystem ) ); 897 } 898 899 // The ogc_wpvs schema says: wgs84 is mandatory therefore-> not checking parents to use it's 900 // bboxes. 901 902 // if ( parent != null ) { 903 // Envelope[] boundingBoxes = parent.getBoundingBoxes(); 904 // for ( int i = 0; i < boundingBoxes.length; i++ ) { 905 // bboxesList.add( boundingBoxes[i] ); 906 // } 907 // } 908 909 Envelope[] boxes = bboxesList.toArray( new Envelope[bboxesList.size()] ); 910 return boxes; 911 } 912 913 /** 914 * Usable with any BoundingBox. Changed crs from null to given attribute value of crs. Added check for min values to 915 * be smaler than max values. 916 * 917 * Creates an <code>Envelope</code> object from the given element of type <code>ows:WGS84BoundingBox</code> or 918 * <code>ows:BoundingBox</code>. 919 * 920 * @param element 921 * @param defaultCoordinateSystem 922 * if the crs-attribute of the bbox element is not defined 923 * @return a boundingbox of a dataset 924 * @throws XMLParsingException 925 * @throws InvalidParameterValueException 926 */ 927 protected Envelope parseBoundingBox( Element element, CoordinateSystem defaultCoordinateSystem ) 928 throws XMLParsingException, 929 InvalidParameterValueException { 930 931 // Envelope env = getWGS84BoundingBoxType( element ); 932 933 String crsAtt = element.getAttribute( "crs" ); 934 CoordinateSystem crs = null; 935 if ( crsAtt == null ) { 936 crs = defaultCoordinateSystem; 937 } else { 938 try { 939 crs = CRSFactory.create( crsAtt ); 940 } catch ( UnknownCRSException e ) { 941 throw new InvalidParameterValueException( e.getMessage() ); 942 } 943 } 944 945 double[] lowerCorner = XMLTools.getRequiredNodeAsDoubles( element, 946 PRE_OWS + "LowerCorner/text()", 947 nsContext, 948 " " ); 949 if ( lowerCorner.length < 2 ) { 950 throw new XMLParsingException( Messages.getMessage( "WPVS_NO_VALID_BBOX_POINT", PRE_OWS + "LowerCorner" ) ); 951 } 952 double[] upperCorner = XMLTools.getRequiredNodeAsDoubles( element, 953 PRE_OWS + "UpperCorner/text()", 954 nsContext, 955 " " ); 956 if ( upperCorner.length < 2 ) { 957 throw new XMLParsingException( Messages.getMessage( "WPVS_NO_VALID_BBOX_POINT", PRE_OWS + "UpperCorner" ) ); 958 } 959 if ( upperCorner.length != lowerCorner.length ) { 960 throw new XMLParsingException( Messages.getMessage( "WPVS_DIFFERENT_BBOX_DIMENSIONS", 961 PRE_OWS + "LowerCorner", 962 PRE_OWS + "UpperCorner" ) ); 963 } 964 965 for ( int i = 0; i < upperCorner.length; ++i ) { 966 if ( lowerCorner[i] >= upperCorner[i] ) { 967 throw new InvalidParameterValueException( Messages.getMessage( "WPVS_WRONG_BBOX_POINT_POSITIONS", 968 new Integer( i ), 969 new Double( lowerCorner[i] ), 970 PRE_OWS + "LowerCorner", 971 new Double( upperCorner[i] ), 972 PRE_OWS + "UpperCorner" ) ); 973 974 } 975 } 976 977 return GeometryFactory.createEnvelope( lowerCorner[0], lowerCorner[1], upperCorner[0], upperCorner[1], crs ); 978 979 } 980 981 /** 982 * Creates and returns a new <code>OperationsMetadata</code> object. 983 * 984 * @param defaultOnlineResource 985 * to fill in the left out dcp's or <code>null</code> if no default URL was given. 986 * 987 * @return Returns a new OperationsMetadata object. 988 * @throws XMLParsingException 989 * @throws InvalidCapabilitiesException 990 */ 991 protected OperationsMetadata parseOperationsMetadata( OnlineResource defaultOnlineResource ) 992 throws XMLParsingException, 993 InvalidCapabilitiesException { 994 995 Node operationMetadata = XMLTools.getRequiredNode( getRootElement(), PRE_OWS + "OperationsMetadata", nsContext ); 996 List<Node> operationElementList = XMLTools.getNodes( operationMetadata, PRE_OWS + "Operation", nsContext ); 997 998 Map<String, Element> operations = new HashMap<String, Element>(); 999 for ( int i = 0; i < operationElementList.size(); i++ ) { 1000 operations.put( XMLTools.getRequiredNodeAsString( operationElementList.get( i ), "@name", nsContext ), 1001 (Element) operationElementList.get( i ) ); 1002 } 1003 1004 Operation110 getCapabilities = getOperation110( OperationsMetadata.GET_CAPABILITIES_NAME, 1005 true, 1006 operations, 1007 defaultOnlineResource ); 1008 Operation110 getView = getOperation110( WPVSOperationsMetadata.GET_VIEW_NAME, 1009 true, 1010 operations, 1011 defaultOnlineResource ); 1012 Operation110 getDescription = getOperation110( WPVSOperationsMetadata.GET_DESCRIPTION_NAME, 1013 false, 1014 operations, 1015 defaultOnlineResource ); 1016 1017 Operation110 get3DFeatureInfo = getOperation110( WPVSOperationsMetadata.GET_3D_FEATURE_INFO, 1018 false, 1019 operations, 1020 defaultOnlineResource ); 1021 1022 Operation110 getLegendGraphics = getOperation110( WPVSOperationsMetadata.GET_LEGEND_GRAPHIC_NAME, 1023 false, 1024 operations, 1025 defaultOnlineResource ); 1026 1027 List<Node> parameterElementList = XMLTools.getNodes( operationMetadata, PRE_OWS + "Parameter", nsContext ); 1028 OWSDomainType110[] parameters = new OWSDomainType110[parameterElementList.size()]; 1029 for ( int i = 0; i < parameters.length; i++ ) { 1030 parameters[i] = getOWSDomainType110( (Element) parameterElementList.get( i ) ); 1031 } 1032 1033 List<Node> constraintElementList = XMLTools.getNodes( operationMetadata, PRE_OWS + "Constraint", nsContext ); 1034 OWSDomainType110[] constraints = new OWSDomainType110[constraintElementList.size()]; 1035 for ( int i = 0; i < constraints.length; i++ ) { 1036 constraints[i] = getOWSDomainType110( (Element) constraintElementList.get( i ) ); 1037 } 1038 1039 List<Node> extendedCapsList = XMLTools.getNodes( operationMetadata, PRE_OWS + "ExtendedCapabilities", nsContext ); 1040 Object[] extendedCapabilities = new Object[extendedCapsList.size()]; 1041 for ( int i = 0; i < extendedCapabilities.length; i++ ) { 1042 extendedCapabilities[i] = extendedCapsList.get( i ); 1043 } 1044 1045 WPVSOperationsMetadata metadata = new WPVSOperationsMetadata( getCapabilities, 1046 getView, 1047 getDescription, 1048 getLegendGraphics, 1049 parameters, 1050 constraints, 1051 extendedCapabilities, 1052 get3DFeatureInfo ); 1053 1054 return metadata; 1055 } 1056 1057 /** 1058 * FIXME needs to be handled, when OWSDomainType110 ceases to exist. 1059 * 1060 * @see org.deegree.owscommon.OWSCommonCapabilitiesDocument#getOperation(String, boolean, Map) 1061 * 1062 * @param name 1063 * @param isMandatory 1064 * @param operations 1065 * @return the Operation110 with the given name from the map 1066 * @throws XMLParsingException 1067 * @throws InvalidCapabilitiesException 1068 */ 1069 private Operation110 getOperation110( String name, boolean isMandatory, Map<String, Element> operations, 1070 OnlineResource defaultOnlineResource ) 1071 throws XMLParsingException, 1072 InvalidCapabilitiesException { 1073 1074 Operation110 operation = null; 1075 Element operationElement = operations.get( name ); 1076 if ( operationElement == null ) { 1077 if ( isMandatory ) { 1078 throw new XMLParsingException( "Mandatory operation '" + name 1079 + "' not defined in " 1080 + "'OperationsMetadata'-section." ); 1081 } 1082 } else { 1083 // 'ows:DCP' - elements 1084 DCPType[] dcps = getDCPs( XMLTools.getRequiredElements( operationElement, PRE_OWS + "DCP", nsContext ) ); 1085 //fill in the default online resource if one is missing. 1086 if ( defaultOnlineResource != null ) { 1087 for ( DCPType dcp : dcps ) { 1088 Protocol pr = dcp.getProtocol(); 1089 if ( pr != null ) { 1090 if ( pr instanceof HTTP ) { 1091 if ( ( (HTTP) pr ).getGetOnlineResources() == null || ( (HTTP) pr ).getGetOnlineResources().length == 0 ) { 1092 ( (HTTP) pr ).setGetOnlineResources( new URL[] { defaultOnlineResource.getLinkage() 1093 .getHref() } ); 1094 } 1095 if ( ( (HTTP) pr ).getPostOnlineResources() == null || ( (HTTP) pr ).getPostOnlineResources().length == 0 ) { 1096 ( (HTTP) pr ).setPostOnlineResources( new URL[] { defaultOnlineResource.getLinkage() 1097 .getHref() } ); 1098 } 1099 } 1100 } 1101 } 1102 } 1103 1104 // 'Parameter' - elements 1105 List<Node> parameterList = XMLTools.getNodes( operationElement, PRE_OWS + "Parameter", nsContext ); 1106 OWSDomainType110[] parameters = new OWSDomainType110[parameterList.size()]; 1107 for ( int i = 0; i < parameters.length; i++ ) { 1108 parameters[i] = getOWSDomainType110( (Element) parameterList.get( i ) ); 1109 } 1110 // 'Constraint' - elements 1111 List<Node> constraintList = XMLTools.getNodes( operationElement, PRE_OWS + "Constraint", nsContext ); 1112 OWSDomainType110[] constraints = new OWSDomainType110[constraintList.size()]; 1113 for ( int i = 0; i < constraintList.size(); i++ ) { 1114 constraints[i] = getOWSDomainType110( (Element) constraintList.get( i ) ); 1115 } 1116 // 'ows:Metadata' - element 1117 List<Node> metadataList = XMLTools.getNodes( operationElement, PRE_OWS + "Metadata", nsContext ); 1118 OWSMetadata[] metadata = new OWSMetadata[metadataList.size()]; 1119 for ( int i = 0; i < metadata.length; i++ ) { 1120 metadata[i] = getOWSMetadata( operationElement, PRE_OWS + "Metadata", nsContext ); 1121 } 1122 1123 // return new Operation110 object 1124 operation = new Operation110( name, dcps, parameters, constraints, metadata ); 1125 } 1126 1127 return operation; 1128 } 1129 1130 /** 1131 * FIXME there is a similar method in org.deegree.owscommon.OWSCommonCapabilitiesDocument#getDCP. overrides that 1132 * method! 1133 * 1134 * Creates a <code>DCPType</code> object from the passed <code>DCP</code> element. 1135 * 1136 * @param element 1137 * @return created <code>DCPType</code> 1138 * @throws XMLParsingException 1139 * @see org.deegree.ogcwebservices.getcapabilities.OGCStandardCapabilities 1140 */ 1141 @Override 1142 protected DCPType getDCP( Element element ) 1143 throws XMLParsingException { 1144 DCPType dcpType = null; 1145 Element httpElement = (Element) XMLTools.getRequiredNode( element, PRE_OWS + "HTTP", nsContext ); 1146 1147 try { 1148 List<Node> requestList = XMLTools.getNodes( httpElement, PRE_OWS + "Get", nsContext ); 1149 OWSRequestMethod[] getRequests = new OWSRequestMethod[requestList.size()]; 1150 for ( int i = 0; i < getRequests.length; i++ ) { 1151 1152 List<Node> constraintList = XMLTools.getNodes( requestList.get( i ), PRE_OWS + "Constraint", nsContext ); 1153 OWSDomainType110[] constraint = new OWSDomainType110[constraintList.size()]; 1154 for ( int j = 0; j < constraint.length; j++ ) { 1155 constraint[j] = getOWSDomainType110( (Element) constraintList.get( i ) ); 1156 } 1157 1158 SimpleLink link = parseSimpleLink( (Element) requestList.get( i ) ); 1159 1160 getRequests[i] = new OWSRequestMethod( link, constraint ); 1161 } 1162 1163 requestList = XMLTools.getNodes( httpElement, PRE_OWS + "Post", nsContext ); 1164 OWSRequestMethod[] postRequests = new OWSRequestMethod[requestList.size()]; 1165 for ( int i = 0; i < postRequests.length; i++ ) { 1166 1167 List<Node> constraintList = XMLTools.getNodes( requestList.get( i ), PRE_OWS + "Constraint", nsContext ); 1168 OWSDomainType110[] constraint = new OWSDomainType110[constraintList.size()]; 1169 for ( int j = 0; j < constraint.length; j++ ) { 1170 constraint[j] = getOWSDomainType110( (Element) constraintList.get( i ) ); 1171 } 1172 1173 SimpleLink link = parseSimpleLink( (Element) requestList.get( i ) ); 1174 1175 postRequests[i] = new OWSRequestMethod( link, constraint ); 1176 } 1177 1178 Protocol protocol = new HTTP110( getRequests, postRequests ); 1179 dcpType = new DCPType( protocol ); 1180 1181 } catch ( InvalidCapabilitiesException e ) { 1182 throw new XMLParsingException( "Couldn't parse the OWSDomainType110 within DCPType: " + StringTools.stackTraceToString( e ) ); 1183 } 1184 1185 return dcpType; 1186 } 1187 1188 /** 1189 * FIXME needs to be handled, when OWSDomainType110 ceases to exist. 1190 * 1191 * @see org.deegree.owscommon.OWSCommonCapabilitiesDocument#getOWSDomainType(String, Element) 1192 * 1193 * @param element 1194 * @return Returns owsDomainType110 object. 1195 * @throws InvalidCapabilitiesException 1196 */ 1197 private OWSDomainType110 getOWSDomainType110( Element element ) 1198 throws XMLParsingException, 1199 InvalidCapabilitiesException { 1200 1201 // 'name' - attribute 1202 String name = XMLTools.getRequiredNodeAsString( element, "@name", nsContext ); 1203 1204 // 'ows:AllowedValues' - element 1205 Element allowedElement = (Element) XMLTools.getNode( element, PRE_OWS + "AllowedValues", nsContext ); 1206 OWSAllowedValues allowedValues = null; 1207 if ( allowedElement != null ) { 1208 1209 // 'ows:Value' - elements 1210 String[] values = XMLTools.getNodesAsStrings( allowedElement, PRE_OWS + "Value/text()", nsContext ); 1211 TypedLiteral[] literals = null; 1212 if ( values != null ) { 1213 literals = new TypedLiteral[values.length]; 1214 for ( int i = 0; i < literals.length; i++ ) { 1215 literals[i] = new TypedLiteral( values[i], null ); 1216 } 1217 } 1218 1219 // 'ows:Range' - elements 1220 List<Node> rangeList = XMLTools.getNodes( allowedElement, PRE_OWS + "Range", nsContext ); 1221 ValueRange[] ranges = new ValueRange[rangeList.size()]; 1222 for ( int i = 0; i < ranges.length; i++ ) { 1223 String minimum = XMLTools.getNodeAsString( rangeList.get( i ), 1224 PRE_OWS + "MinimumValue", 1225 nsContext, 1226 null ); 1227 String maximum = XMLTools.getNodeAsString( rangeList.get( i ), 1228 PRE_OWS + "MaximumValue", 1229 nsContext, 1230 null ); 1231 String spacing = XMLTools.getNodeAsString( rangeList.get( i ), 1232 PRE_OWS + "Spacing", 1233 nsContext, 1234 null ); 1235 TypedLiteral min = new TypedLiteral( minimum, null ); 1236 TypedLiteral max = new TypedLiteral( maximum, null ); 1237 TypedLiteral space = new TypedLiteral( spacing, null ); 1238 1239 ranges[i] = new ValueRange( min, max, space ); 1240 } 1241 1242 if ( values.length < 1 && ranges.length < 1 ) { 1243 throw new XMLParsingException( "At least one 'ows:Value'-element or one 'ows:Range'-element must be defined " + "in each element of type 'ows:AllowedValues'." ); 1244 } 1245 1246 allowedValues = new OWSAllowedValues( literals, ranges ); 1247 } 1248 1249 // FIXME manage elements: ows:AnyValue, ows:NoValues. 1250 boolean anyValue = false; 1251 boolean noValues = false; 1252 1253 // 'ows:ValuesListReference' - element 1254 OWSMetadata valuesListReference = getOWSMetadata( element, PRE_OWS + "ValuesListReference", nsContext ); 1255 1256 // 'ows:DefaulValue' - element 1257 String defaultValue = XMLTools.getNodeAsString( element, PRE_OWS + "DefaultValue/text()", nsContext, null ); 1258 1259 // 'ows:Meaning' - element 1260 OWSMetadata meaning = getOWSMetadata( element, PRE_OWS + "Meaning", nsContext ); 1261 1262 // 'ows:DataType - element 1263 OWSMetadata dataType = getOWSMetadata( element, PRE_OWS + "DataType", nsContext ); 1264 1265 // choose up to one measurement element 1266 String measurementType = null; 1267 // 'ows:ReferenceSystem' - element 1268 Element referenceElement = (Element) XMLTools.getNode( element, PRE_OWS + "ReferenceSystem", nsContext ); 1269 // 'ows:UOM' - element 1270 Element uomElement = (Element) XMLTools.getNode( element, PRE_OWS + "UOM", nsContext ); 1271 OWSMetadata measurement = null; 1272 1273 if ( referenceElement != null && uomElement != null ) { 1274 throw new InvalidCapabilitiesException( "Within an 'ows:DomainType'-Element only one " + "of the following elements is allowed: " 1275 + "'ows:ReferenceSystem' OR 'ows:UOM'." ); 1276 } else if ( referenceElement != null ) { 1277 measurementType = OWSDomainType110.REFERENCE_SYSTEM; 1278 measurement = getOWSMetadata( element, PRE_OWS + "ReferenceSystem", nsContext ); 1279 } else if ( uomElement != null ) { 1280 measurementType = OWSDomainType110.UOM; 1281 measurement = getOWSMetadata( element, PRE_OWS + "UOM", nsContext ); 1282 } 1283 1284 // 'ows:Metadata' - elements 1285 List<Node> metaList = XMLTools.getNodes( element, PRE_OWS + "Metadata", nsContext ); 1286 OWSMetadata[] metadata = new OWSMetadata[metaList.size()]; 1287 for ( int i = 0; i < metadata.length; i++ ) { 1288 metadata[i] = getOWSMetadata( (Element) metaList.get( i ), PRE_OWS + "Metadata", nsContext ); 1289 } 1290 1291 // return new OWSDomainType110 1292 OWSDomainType110 domainType110 = null; 1293 if ( allowedValues != null && !anyValue && !noValues && valuesListReference == null ) { 1294 domainType110 = new OWSDomainType110( allowedValues, 1295 defaultValue, 1296 meaning, 1297 dataType, 1298 measurementType, 1299 measurement, 1300 metadata, 1301 name ); 1302 } else if ( ( anyValue || noValues ) && allowedValues == null && valuesListReference == null ) { 1303 domainType110 = new OWSDomainType110( anyValue, 1304 noValues, 1305 defaultValue, 1306 meaning, 1307 dataType, 1308 measurementType, 1309 measurement, 1310 metadata, 1311 name ); 1312 } else if ( valuesListReference != null && allowedValues == null && !anyValue && !noValues ) { 1313 domainType110 = new OWSDomainType110( valuesListReference, 1314 defaultValue, 1315 meaning, 1316 dataType, 1317 measurementType, 1318 measurement, 1319 metadata, 1320 name ); 1321 } else { 1322 throw new InvalidCapabilitiesException( "Only one of the following elements may be " + "contained within an 'ows:DomainType': 'ows:AllowedValues', 'ows:AnyValue', " 1323 + "'ows:NoValues' or 'ows:ValuesListReference'." ); 1324 } 1325 1326 return domainType110; 1327 } 1328 1329 /** 1330 * FIXME check, wether the URIs go to the correct address within OWSMetadata. So far, no example was given to check 1331 * this with. 1332 * 1333 * Creates and returns a new <code>OWSMetadata</code> object (or null) from the given <code>Element</code> at 1334 * the given <code>XPath</code>. 1335 * 1336 * @param element 1337 * @param xPath 1338 * @param nsContext 1339 * @return Returns a new OWSMetadata object (may be null). 1340 * @throws XMLParsingException 1341 */ 1342 private OWSMetadata getOWSMetadata( Element element, String xPath, NamespaceContext nsContext ) 1343 throws XMLParsingException { 1344 1345 Element child = (Element) XMLTools.getNode( element, xPath, nsContext ); 1346 1347 if ( child == null ) { 1348 return null; 1349 } 1350 1351 // attrib about 1352 URI about = XMLTools.getNodeAsURI( child, "@about", nsContext, null ); 1353 1354 // attribs for SimpleLink 1355 URI href = XMLTools.getNodeAsURI( child, "@xlink:href", nsContext, null ); 1356 URI role = XMLTools.getNodeAsURI( child, "@xlink:role", nsContext, null ); 1357 URI arcrole = XMLTools.getNodeAsURI( child, "@xlink:arcrole", nsContext, null ); 1358 String title = XMLTools.getNodeAsString( child, "@xlink:title", nsContext, null ); 1359 String show = XMLTools.getNodeAsString( child, "@xlink:show", nsContext, null ); 1360 String actuate = XMLTools.getNodeAsString( child, "@xlink:actuate", nsContext, null ); 1361 1362 // ows:name (ows:AbstractMetaData) 1363 String name = XMLTools.getNodeAsString( child, "text()", nsContext, null ); 1364 1365 SimpleLink link = new SimpleLink( href, role, arcrole, title, show, actuate ); 1366 1367 return new OWSMetadata( about, link, name ); 1368 } 1369 1370 }