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 }