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