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