001 // $HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wcs/describecoverage/CoverageDescriptionDocument.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2008 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53115 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 043 ---------------------------------------------------------------------------*/ 044 package org.deegree.ogcwebservices.wcs.describecoverage; 045 046 import java.io.IOException; 047 import java.net.MalformedURLException; 048 import java.net.URI; 049 import java.net.URISyntaxException; 050 import java.net.URL; 051 052 import org.deegree.datatypes.Code; 053 import org.deegree.datatypes.CodeList; 054 import org.deegree.datatypes.time.TimeSequence; 055 import org.deegree.datatypes.values.Values; 056 import org.deegree.framework.util.StringTools; 057 import org.deegree.framework.xml.ElementList; 058 import org.deegree.framework.xml.XMLParsingException; 059 import org.deegree.framework.xml.XMLTools; 060 import org.deegree.model.crs.UnknownCRSException; 061 import org.deegree.model.metadata.iso19115.Keywords; 062 import org.deegree.model.spatialschema.Envelope; 063 import org.deegree.ogcbase.CommonNamespaces; 064 import org.deegree.ogcbase.GMLDocument; 065 import org.deegree.ogcbase.InvalidGMLException; 066 import org.deegree.ogcbase.OGCDocument; 067 import org.deegree.ogcbase.OGCException; 068 import org.deegree.ogcwebservices.LonLatEnvelope; 069 import org.deegree.ogcwebservices.MetadataLink; 070 import org.deegree.ogcwebservices.MetadataType; 071 import org.deegree.ogcwebservices.OGCWebServiceException; 072 import org.deegree.ogcwebservices.SupportedFormats; 073 import org.deegree.ogcwebservices.SupportedSRSs; 074 import org.deegree.ogcwebservices.wcs.InterpolationMethod; 075 import org.deegree.ogcwebservices.wcs.SupportedInterpolations; 076 import org.deegree.ogcwebservices.wcs.WCSException; 077 import org.deegree.ogcwebservices.wcs.configuration.Extension; 078 import org.deegree.ogcwebservices.wcs.configuration.ExtensionDocument; 079 import org.w3c.dom.Element; 080 import org.xml.sax.SAXException; 081 082 /** 083 * <ul> 084 * <li> usage of srsName from gml:Envelope is not supoorted yet. deegree Envelope doesn't uses CRSs 085 * <li> gml:Grid and gml:Polygon is not yet supported by the deegree WCS 086 * </ul> 087 * 088 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 089 * @author last edited by: $Author: apoth $ 090 * 091 * @version $Revision: 9345 $, $Date: 2007-12-27 17:22:25 +0100 (Do, 27 Dez 2007) $ 092 */ 093 public class CoverageDescriptionDocument extends OGCDocument { 094 095 public static final String XML_TEMPLATE = "CoverageDescriptionTemplate.xml"; 096 097 private static URI WCSNS = CommonNamespaces.WCSNS; 098 099 private static URI GMLNS = CommonNamespaces.GMLNS; 100 101 private static URI DGRNS = CommonNamespaces.DEEGREEWCS; 102 103 /** 104 * @throws IOException 105 * @throws SAXException 106 * @see "org.deegree.framework.xml.XMLFragment#createEmptyDocument()" 107 */ 108 public void createEmptyDocument() 109 throws IOException, SAXException { 110 URL url = CoverageDescriptionDocument.class.getResource( XML_TEMPLATE ); 111 if ( url == null ) { 112 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." ); 113 } 114 load( url ); 115 } 116 117 /** 118 * returns the version of the CoverageDescription 119 * 120 * @return the version of the CoverageDescription 121 * @throws InvalidCoverageDescriptionExcpetion 122 */ 123 public String getVersion() 124 throws InvalidCoverageDescriptionExcpetion { 125 try { 126 return XMLTools.getRequiredAttrValue( "version", null, getRootElement() ); 127 } catch ( XMLParsingException e ) { 128 String s = e.getMessage() + "\n" + StringTools.stackTraceToString( e ); 129 throw new InvalidCoverageDescriptionExcpetion( s ); 130 } 131 } 132 133 /** 134 * creates a <tt>CoverageDescription</tt> instance from the DOM document encapsulated by this 135 * class 136 * 137 * @return created <tt>CoverageDescription</tt> instance 138 * @throws InvalidCoverageDescriptionExcpetion 139 * @throws UnknownCRSException 140 */ 141 public CoverageOffering[] getCoverageOfferings() 142 throws InvalidCoverageDescriptionExcpetion, UnknownCRSException { 143 144 try { 145 ElementList el = XMLTools.getChildElements( "CoverageOffering", WCSNS, getRootElement() ); 146 CoverageOffering[] co = getCoverageOfferings( el ); 147 return co; 148 } catch ( XMLParsingException e ) { 149 String s = e.getMessage() + "\n" + StringTools.stackTraceToString( e ); 150 throw new InvalidCoverageDescriptionExcpetion( s ); 151 } catch ( WCSException e ) { 152 String s = e.getMessage() + "\n" + StringTools.stackTraceToString( e ); 153 throw new InvalidCoverageDescriptionExcpetion( s ); 154 } catch ( OGCException e ) { 155 String s = e.getMessage() + "\n" + StringTools.stackTraceToString( e ); 156 throw new InvalidCoverageDescriptionExcpetion( s ); 157 } 158 159 } 160 161 /** 162 * creates an array of <tt>CoverageOffering</tt> objects contained in the enclosing 163 * CoverageDescrption element. 164 * 165 * @param el 166 * list of CoverageOffering elements 167 * @return array of <tt>CoverageOffering</tt> objects 168 * @throws XMLParsingException 169 * @throws UnknownCRSException 170 */ 171 private CoverageOffering[] getCoverageOfferings( ElementList el ) 172 throws XMLParsingException, WCSException, OGCException, 173 UnknownCRSException { 174 CoverageOffering[] co = new CoverageOffering[el.getLength()]; 175 176 for ( int i = 0; i < co.length; i++ ) { 177 co[i] = getCoverageOffering( el.item( i ) ); 178 } 179 180 return co; 181 } 182 183 /** 184 * @param element 185 * @return 186 * @throws XMLParsingException 187 * @throws UnknownCRSException 188 */ 189 private CoverageOffering getCoverageOffering( Element element ) 190 throws XMLParsingException, WCSException, OGCException, 191 UnknownCRSException { 192 193 String name = XMLTools.getRequiredStringValue( "name", WCSNS, element ); 194 String label = XMLTools.getStringValue( "label", WCSNS, element, name ); 195 String desc = XMLTools.getStringValue( "description", WCSNS, element, null ); 196 Element elem = XMLTools.getChildElement( "metadataLink", WCSNS, element ); 197 MetadataLink mLink = parseMetadataLink( elem ); 198 elem = XMLTools.getRequiredChildElement( "lonLatEnvelope", WCSNS, element ); 199 LonLatEnvelope lonLatEnvelope = parseLonLatEnvelope( elem ); 200 ElementList el = XMLTools.getChildElements( "keywords", WCSNS, element ); 201 Keywords[] keywords = parseKeywords( el, WCSNS ); 202 elem = XMLTools.getRequiredChildElement( "domainSet", WCSNS, element ); 203 DomainSet domainSet = getDomainSet( elem ); 204 RangeSet rangeSet = null; 205 elem = XMLTools.getRequiredChildElement( "rangeSet", WCSNS, element ); 206 if ( elem != null ) { 207 elem = XMLTools.getRequiredChildElement( "RangeSet", WCSNS, elem ); 208 rangeSet = getRangeSet( elem ); 209 } 210 elem = XMLTools.getRequiredChildElement( "supportedCRSs", WCSNS, element ); 211 SupportedSRSs supportedCRSs = getSupportedCRSs( elem ); 212 elem = XMLTools.getRequiredChildElement( "supportedFormats", WCSNS, element ); 213 SupportedFormats supportedFormats = getSupportedFomarts( elem ); 214 elem = XMLTools.getRequiredChildElement( "supportedInterpolations", WCSNS, element ); 215 SupportedInterpolations supInterpol = getSupportedInterpolations( elem ); 216 elem = XMLTools.getRequiredChildElement( "Extension", DGRNS, element ); 217 218 ExtensionDocument eb = new ExtensionDocument( elem, getSystemId() ); 219 Extension extension = eb.getExtension(); 220 221 return new CoverageOffering( name, label, desc, mLink, lonLatEnvelope, keywords, domainSet, 222 rangeSet, supportedCRSs, supportedFormats, supInterpol, 223 extension ); 224 } 225 226 /** 227 * creates a <tt>MetadataLink</tt> object from the passed element. 228 * 229 * @param element 230 * @return created <tt>MetadataLink</tt> 231 * @throws XMLParsingException 232 */ 233 private MetadataLink parseMetadataLink( Element element ) 234 throws XMLParsingException { 235 if ( element == null ) 236 return null; 237 238 try { 239 URL reference = new URL( XMLTools.getAttrValue( element, "xlink:href" ) ); 240 String title = XMLTools.getAttrValue( element, "xlink:title" ); 241 URI about = new URI( XMLTools.getAttrValue( element, null, "about", null ) ); 242 String tmp = XMLTools.getAttrValue( element, null, "metadataType", null ); 243 MetadataType metadataType = new MetadataType( tmp ); 244 245 return new MetadataLink( reference, title, about, metadataType ); 246 } catch ( MalformedURLException e ) { 247 throw new XMLParsingException( "Couldn't parse metadataLink reference\n" 248 + StringTools.stackTraceToString( e ) ); 249 } catch ( URISyntaxException e ) { 250 throw new XMLParsingException( "Couldn't parse metadataLink about\n" 251 + StringTools.stackTraceToString( e ) ); 252 } 253 } 254 255 /** 256 * creates a <tt>DomainSet</tt> from the passed element. Not all possible sub elements are 257 * supported at the moment by deegree (see class comment) 258 * 259 * @param element 260 * @return 261 * @throws XMLParsingException 262 * @throws InvalidCoverageDescriptionExcpetion 263 * @throws WCSException 264 * @throws UnknownCRSException 265 */ 266 private DomainSet getDomainSet( Element element ) 267 throws XMLParsingException, InvalidCoverageDescriptionExcpetion, 268 WCSException, UnknownCRSException { 269 Element elem = XMLTools.getRequiredChildElement( "spatialDomain", WCSNS, element ); 270 SpatialDomain sd = getSpatialDomain( elem ); 271 elem = XMLTools.getChildElement( "temporalDomain", WCSNS, element ); 272 TimeSequence seq = null; 273 if ( elem != null ) { 274 try { 275 seq = parseTimeSequence( elem, WCSNS ); 276 } catch ( OGCWebServiceException e ) { 277 String s = e.getMessage() + "\n" + StringTools.stackTraceToString( e ); 278 throw new InvalidCoverageDescriptionExcpetion( s ); 279 } 280 } 281 return new DomainSet( sd, seq ); 282 } 283 284 /** 285 * creates a <tt>SpatialDomain</tt> object from the passe element. At the moment deegree 286 * doesn't support gml:Grid and gml:Polygon elements for defining a spatial domain of a 287 * coverage. 288 * 289 * @param element 290 * @return created <tt>SpatialDomain</tt> 291 * @throws XMLParsingException 292 * @throws InvalidCoverageDescriptionExcpetion 293 * @throws WCSException 294 * @throws UnknownCRSException 295 */ 296 private SpatialDomain getSpatialDomain( Element element ) 297 throws InvalidCoverageDescriptionExcpetion, WCSException, 298 UnknownCRSException { 299 if ( XMLTools.getChildElement( "Grid", GMLNS, element ) != null ) { 300 throw new InvalidCoverageDescriptionExcpetion( "GML Grid for SpatialDomain is not " 301 + "supported by the deegree WCS yet." ); 302 } 303 if ( XMLTools.getChildElement( "Polygon", GMLNS, element ) != null ) { 304 throw new InvalidCoverageDescriptionExcpetion( "GML Polygon for SpatialDomain is not " 305 + "supported by the deegree WCS yet." ); 306 } 307 ElementList el = XMLTools.getChildElements( "Envelope", GMLNS, element ); 308 Envelope[] envelops = getEnvelopes( el ); 309 return new SpatialDomain( envelops ); 310 } 311 312 /** 313 * creates an array of <tt>Envelope</tt>s from the passed element list 314 * 315 * @param el 316 * @return created array of <tt>Envelope</tt>s 317 * @throws XMLParsingException 318 * @throws InvalidCoverageDescriptionExcpetion 319 * @throws UnknownCRSException 320 */ 321 private Envelope[] getEnvelopes( ElementList el ) 322 throws InvalidCoverageDescriptionExcpetion, UnknownCRSException { 323 if ( el.getLength() == 0 ) { 324 throw new InvalidCoverageDescriptionExcpetion( "at least one envelope must be" 325 + "defined in a spatialDomain" ); 326 } 327 Envelope[] envelopes = new Envelope[el.getLength()]; 328 for ( int i = 0; i < envelopes.length; i++ ) { 329 try { 330 envelopes[i] = GMLDocument.parseEnvelope( el.item( i ) ); 331 } catch ( InvalidGMLException e ) { 332 String s = e.getMessage() + "\n" + StringTools.stackTraceToString( e ); 333 throw new InvalidCoverageDescriptionExcpetion( s ); 334 } 335 } 336 return envelopes; 337 } 338 339 /** 340 * creates a <tt>RangeSet</tt> object from the passed element 341 * 342 * @param element 343 * @return created <tt>RangeSet</tt> 344 * @throws XMLParsingException 345 * @throws WCSException 346 * @throws OGCException 347 */ 348 private RangeSet getRangeSet( Element element ) 349 throws XMLParsingException, WCSException, OGCException { 350 try { 351 String name = XMLTools.getRequiredStringValue( "name", WCSNS, element ); 352 String label = XMLTools.getStringValue( "label", WCSNS, element, name ); 353 String desc = XMLTools.getStringValue( "description", WCSNS, element, null ); 354 Element elem = XMLTools.getChildElement( "metadataLink", WCSNS, element ); 355 MetadataLink mLink = parseMetadataLink( elem ); 356 String tmp = XMLTools.getAttrValue( element, null, "semantic", null ); 357 URI semantic = null; 358 if ( tmp != null ) { 359 semantic = new URI( tmp ); 360 } 361 362 tmp = XMLTools.getAttrValue( element, null, "refSys", null ); 363 URI refSys = null; 364 if ( tmp != null ) { 365 refSys = new URI( tmp ); 366 } 367 368 String refSysLabel = XMLTools.getAttrValue( element, null, "refSysLabel", null ); 369 370 AxisDescription[] axisDescription = null; 371 ElementList el = XMLTools.getChildElements( "axisDescription", WCSNS, element ); 372 if ( elem != null ) { 373 elem = XMLTools.getChildElement( "AxisDescription", WCSNS, element ); 374 axisDescription = getAxisDescriptions( el ); 375 } 376 elem = XMLTools.getChildElement( "nullValues", WCSNS, element ); 377 Values nullValues = parseValues( elem, WCSNS ); 378 return new RangeSet( name, label, desc, mLink, semantic, refSys, refSysLabel, 379 nullValues, axisDescription ); 380 } catch ( URISyntaxException e ) { 381 throw new XMLParsingException( "couldn't parse URI from typedLiteral\n" 382 + StringTools.stackTraceToString( e ) ); 383 } 384 385 } 386 387 /** 388 * creates an array of <tt>AxisDescription</tt>s from the passed element list 389 * 390 * @param el 391 * @return created array of <tt>AxisDescription</tt>s 392 * @throws XMLParsingException 393 * @throws WCSException 394 * @throws OGCException 395 */ 396 private AxisDescription[] getAxisDescriptions( ElementList el ) 397 throws XMLParsingException, WCSException, OGCException { 398 AxisDescription[] ad = new AxisDescription[el.getLength()]; 399 for ( int i = 0; i < ad.length; i++ ) { 400 Element elem = XMLTools.getRequiredChildElement( "AxisDescription", WCSNS, el.item( i ) ); 401 ad[i] = getAxisDescription( elem ); 402 } 403 return ad; 404 } 405 406 /** 407 * creates an <tt>AxisDescription</tt> object from the passed element 408 * 409 * @param element 410 * @return created <tt>AxisDescription</tt> 411 * @throws XMLParsingException 412 * @throws WCSException 413 * @throws OGCException 414 */ 415 private AxisDescription getAxisDescription( Element element ) 416 throws XMLParsingException, WCSException, OGCException { 417 try { 418 String tmp = XMLTools.getAttrValue( element, null, "semantic", null ); 419 URI semantic = null; 420 if ( tmp != null ) { 421 semantic = new URI( tmp ); 422 } 423 424 tmp = XMLTools.getAttrValue( element, null, "refSys", null ); 425 URI refSys = null; 426 if ( tmp != null ) { 427 refSys = new URI( tmp ); 428 } 429 430 String refSysLabel = XMLTools.getAttrValue( element, null, "refSysLabel", null ); 431 432 String name = XMLTools.getRequiredStringValue( "name", WCSNS, element ); 433 String label = XMLTools.getStringValue( "label", WCSNS, element, name ); 434 String desc = XMLTools.getStringValue( "description", WCSNS, element, null ); 435 Element elem = XMLTools.getChildElement( "metadataLink", WCSNS, element ); 436 MetadataLink mLink = parseMetadataLink( elem ); 437 elem = XMLTools.getRequiredChildElement( "values", WCSNS, element ); 438 Values values = parseValues( elem, WCSNS ); 439 return new AxisDescription( name, label, desc, mLink, semantic, refSys, refSysLabel, 440 values ); 441 } catch ( URISyntaxException e ) { 442 throw new XMLParsingException( "couldn't parse URI from AxisDescription\n" 443 + StringTools.stackTraceToString( e ) ); 444 } 445 } 446 447 /** 448 * creates a <tt>SupportedSRSs</tt> object from the passed element 449 * 450 * @param element 451 * @return created <tt>SupportedSRSs</tt> 452 * @throws XMLParsingException 453 */ 454 private SupportedSRSs getSupportedCRSs( Element element ) 455 throws XMLParsingException { 456 ElementList el = XMLTools.getChildElements( "requestResponseCRSs", WCSNS, element ); 457 CodeList[] requestResponseCRSs = parseCodeListArray( el ); 458 el = XMLTools.getChildElements( "requestCRSs", WCSNS, element ); 459 CodeList[] requestCRSs = parseCodeListArray( el ); 460 el = XMLTools.getChildElements( "responseCRSs", WCSNS, element ); 461 CodeList[] responseCRSs = parseCodeListArray( el ); 462 el = XMLTools.getChildElements( "nativeCRSs", WCSNS, element ); 463 CodeList[] nativeCRSs = parseCodeListArray( el ); 464 return new SupportedSRSs( requestResponseCRSs, requestCRSs, responseCRSs, nativeCRSs ); 465 } 466 467 /** 468 * creates a <tt>SupportedFormats</tt> object from the passed element 469 * 470 * @param element 471 * @return 472 * @throws XMLParsingException 473 */ 474 private SupportedFormats getSupportedFomarts( Element element ) 475 throws XMLParsingException { 476 String nativeFormat = XMLTools.getAttrValue( element, null, "nativeFormat", null ); 477 ElementList el = XMLTools.getChildElements( "formats", WCSNS, element ); 478 CodeList[] formats = parseCodeListArray( el ); 479 Code nativeF = new Code( nativeFormat ); 480 return new SupportedFormats( formats, nativeF ); 481 } 482 483 /** 484 * creates a <tt>SupportedInterpolations<tt> object from the passed element 485 * @param element 486 * @return created <tt>SupportedInterpolations<tt> 487 * @throws XMLParsingException 488 */ 489 private SupportedInterpolations getSupportedInterpolations( Element element ) { 490 String tmp = XMLTools.getAttrValue( element, null, "default", "nearest neighbor" ); 491 InterpolationMethod def = new InterpolationMethod( tmp ); 492 493 ElementList el = XMLTools.getChildElements( "interpolationMethod", WCSNS, element ); 494 InterpolationMethod[] ims = new InterpolationMethod[el.getLength()]; 495 for ( int i = 0; i < ims.length; i++ ) { 496 tmp = XMLTools.getStringValue( el.item( i ) ); 497 ims[i] = new InterpolationMethod( tmp ); 498 } 499 return new SupportedInterpolations( ims, def ); 500 } 501 502 }