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