001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/wps/describeprocess/ProcessDescriptionDocument.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2005 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/exse/
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    package org.deegree.ogcwebservices.wps.describeprocess;
044    
045    import static org.deegree.ogcbase.CommonNamespaces.OWSNS;
046    
047    import java.net.URI;
048    import java.net.URISyntaxException;
049    import java.util.ArrayList;
050    import java.util.List;
051    
052    import org.deegree.datatypes.Code;
053    import org.deegree.datatypes.values.Closure;
054    import org.deegree.datatypes.values.TypedLiteral;
055    import org.deegree.datatypes.values.ValueRange;
056    import org.deegree.datatypes.xlink.SimpleLink;
057    import org.deegree.framework.xml.XMLFragment;
058    import org.deegree.framework.xml.XMLParsingException;
059    import org.deegree.framework.xml.XMLTools;
060    import org.deegree.ogcwebservices.MetadataType;
061    import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescription.DataInputs;
062    import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescription.ProcessOutputs;
063    import org.deegree.owscommon.OWSMetadata;
064    import org.deegree.owscommon.com110.OWSAllowedValues;
065    import org.w3c.dom.Element;
066    
067    /**
068     * ProcessDescriptionDocument.java
069     * 
070     * Created on 10.03.2006. 15:18:02h
071     * 
072     * @author <a href="mailto:christian@kiehle.org">Christian Kiehle</a>
073     * @author <a href="mailto:christian.heier@gmx.de">Christian Heier</a>
074     * 
075     * @version 1.0.
076     * 
077     * @since 2.0
078     */
079    
080    public class ProcessDescriptionDocument extends XMLFragment {
081    
082        /**
083         * 
084         * @return
085         * @throws XMLParsingException
086         */
087    
088        @SuppressWarnings("unchecked")
089        public ProcessDescription parseProcessDescription() throws XMLParsingException {
090    
091            Element root = getRootElement();
092    
093            Element processDescriptionNode = (Element) XMLTools.getRequiredNode(
094                                                                                 root,
095                                                                                 "wps:ProcessDescription",
096                                                                                 nsContext );
097    
098            String responsibleClass = getResponsibleClass( processDescriptionNode );
099    
100            Code identifier = getIdentifier( processDescriptionNode );
101    
102            String title = getTitle( processDescriptionNode );
103    
104            String _abstract = getAbstract( processDescriptionNode );
105    
106            List<MetadataType> metadataTypeList = getMetadata( processDescriptionNode );
107    
108            DataInputs dataInputs = null;
109    
110            ProcessOutputs processOutputs = null;
111    
112            // Get optional attribute "processVersion" from <wps:ProcessDescription>
113            // node
114            String processVersion = null;
115            String versionAttribute = processDescriptionNode.getAttribute( "processVersion" );
116            if ( null != versionAttribute && !"".equals( versionAttribute ) ) {
117                processVersion = versionAttribute;
118            }
119    
120            // Get optional attribute "storeSupported" from <wps:ProcessDescription>
121            // node
122            boolean storeSupported = false;
123            String storeSupportedAttribute = processDescriptionNode.getAttribute( "storeSupported" );
124            if ( null != storeSupportedAttribute && !"".equals( storeSupportedAttribute ) ) {
125                storeSupported = Boolean.valueOf( storeSupportedAttribute );
126            }
127    
128            // Get optional attribute "statusSupported" from
129            // <wps:ProcessDescription> node
130            boolean statusSupported = false;
131            String statusSupportedAttribute = processDescriptionNode.getAttribute( "statusSupported" );
132            if ( null != statusSupportedAttribute && !"".equals( statusSupportedAttribute ) ) {
133                statusSupported = Boolean.valueOf( statusSupportedAttribute );
134            }
135    
136            // Get optional node <wps:DataInputs> from <wps:ProcessDescription> node
137    
138            Element dataInputsNode = (Element) XMLTools.getRequiredNode( processDescriptionNode,
139                                                                         "wps:DataInputs", nsContext );
140    
141            if ( null != dataInputsNode ) {
142    
143                List inputNodesList = XMLTools.getNodes( dataInputsNode, "wps:Input", nsContext );
144    
145                if ( null != inputNodesList && 0 != inputNodesList.size() ) {
146    
147                    int size = inputNodesList.size();
148                    dataInputs = new DataInputs();
149                    List inputDescriptions = new ArrayList<InputDescription>( size );
150                    for ( int i = 0; i < size; i++ ) {
151    
152                        inputDescriptions.add( i,
153                                               getInputDescription( (Element) inputNodesList.get( i ) ) );
154                    }
155                    dataInputs.setInputDescriptions( inputDescriptions );
156                }
157            }
158    
159            // Get mandatory node <wps:ProcessOutputs> from <wps:ProcessDescription>
160            // node.
161    
162            Element processOutputsNode = (Element) XMLTools.getRequiredNode( processDescriptionNode,
163                                                                             "wps:ProcessOutputs",
164                                                                             nsContext );
165    
166            List outputNodesList = XMLTools.getRequiredNodes( processOutputsNode, "wps:Output",
167                                                              nsContext );
168            int size = outputNodesList.size();
169            processOutputs = new ProcessOutputs();
170            processOutputs.output = new ArrayList<OutputDescription>( size );
171            for ( int i = 0; i < size; i++ ) {
172    
173                processOutputs.output.add( i, getOutputDescription( (Element) outputNodesList.get( i ) ) );
174            }
175    
176            return new ProcessDescription( responsibleClass, identifier, title, _abstract,
177                                           processVersion, metadataTypeList, dataInputs,
178                                           processOutputs, statusSupported, storeSupported );
179    
180        }
181    
182        private String getResponsibleClass( Element processDescriptionNode ) throws XMLParsingException {
183    
184            // Get resonsible class for process execution from deegreeParams section
185            String responsibleClass = null;
186            Element deegreeParamsNode = (Element) XMLTools.getRequiredNode( processDescriptionNode,
187                                                                            "deegreewps:deegreeParams",
188                                                                            nsContext );
189            responsibleClass = XMLTools.getRequiredNodeAsString( deegreeParamsNode,
190                                                                 "deegreewps:responsibleClass/text()",
191                                                                 nsContext );
192    
193            return responsibleClass;
194        }
195    
196        /**
197         * @param processDescriptionNode
198         * @throws XMLParsingException
199         */
200        private List<MetadataType> getMetadata( Element e ) throws XMLParsingException {
201            List<MetadataType> metadataTypeList = null;
202    
203            // Get optional nodes <ows:Metadata>
204            List metadataTypeNodes = XMLTools.getNodes( e, "ows:Metadata", nsContext );
205            if ( null != metadataTypeNodes && 0 != metadataTypeNodes.size() ) {
206                int size = metadataTypeNodes.size();
207                metadataTypeList = new ArrayList<MetadataType>( size );
208                for ( int i = 0; i < size; i++ ) {
209                    metadataTypeList.add( i, getMetadataType( (Element) metadataTypeNodes.get( i ) ) );
210                }
211            }
212            return metadataTypeList;
213        }
214    
215        /**
216         * @param processDescriptionNode
217         * @throws XMLParsingException
218         */
219        private String getAbstract( Element e ) throws XMLParsingException {
220            String _abstract = null;
221    
222            // Get optional node <ows:Abstract>
223            String owsAbstract = XMLTools.getNodeAsString( e, "ows:Abstract/text()", nsContext, null );
224            if ( null != owsAbstract && !"".equals( owsAbstract ) ) {
225                _abstract = owsAbstract;
226            }
227            return _abstract;
228        }
229    
230        /**
231         * @param processDescriptionNode
232         * @throws XMLParsingException
233         */
234        private String getTitle( Element e ) throws XMLParsingException {
235            // Get required node <ows:Title>
236            return XMLTools.getRequiredNodeAsString( e, "ows:Title/text()", nsContext );
237        }
238    
239        /**
240         * @param processDescriptionNode
241         * @throws XMLParsingException
242         */
243        private Code getIdentifier( Element e ) throws XMLParsingException {
244            // Get required node <ows:Identifier>
245            String identifierAsString = XMLTools.getRequiredNodeAsString( e, "ows:Identifier/text()",
246                                                                          nsContext );
247            return new Code( identifierAsString, null );
248        }
249    
250        /**
251         * Creates an object representation of a <code>ows:Metadata</code>
252         * section.
253         * 
254         * @param metadataTypeNode
255         * @return object representation of the <code>ows:Metadata</code> section
256         */
257        private MetadataType getMetadataType( Element metadataTypeNode ) {
258    
259            // FIXME MetadataType contained in Deegree does not correspond with
260            // current OWS MetadataType definition
261            MetadataType metadataType = null;
262    
263            // Only attribute xlink:title supported by now, e.g. <ows:Metadata
264            // xlink:title="buffer"/>
265            String title = metadataTypeNode.getAttributeNS( XLNNS.toString(), "title" );
266    
267            if ( null != title && !"".equals( title ) ) {
268                metadataType = new MetadataType();
269                metadataType.value = title;
270            }
271    
272            return metadataType;
273        }
274    
275        private InputDescription getInputDescription( Element inputDescriptionNode ) throws XMLParsingException {
276    
277            Code identifier = getIdentifier( inputDescriptionNode );
278    
279            String title = getTitle( inputDescriptionNode );
280    
281            String _abstract = getAbstract( inputDescriptionNode );
282    
283            ComplexData complexData = null;
284    
285            LiteralInput literalData = null;
286    
287            SupportedCRSs boundingBoxData = null;
288    
289            Element boundingBoxDataNode = (Element) XMLTools.getNode( inputDescriptionNode,
290                                                                      "wps:BoundingBoxData", nsContext );
291    
292            Element complexDataNode = (Element) XMLTools.getNode( inputDescriptionNode,
293                                                                  "wps:ComplexData", nsContext );
294    
295            Element literalDataNode = (Element) XMLTools.getNode( inputDescriptionNode,
296                                                                  "wps:LiteralData", nsContext );
297    
298            if ( null == boundingBoxDataNode && null == complexDataNode && null == literalDataNode ) {
299                throw new XMLParsingException( "A required data type is missing!" );
300            }
301    
302            if ( null != boundingBoxDataNode && null == complexDataNode && null == literalDataNode ) {
303                boundingBoxData = getSupportedCRSsType( boundingBoxDataNode );
304            }
305            if ( null == boundingBoxDataNode && null != complexDataNode && null == literalDataNode ) {
306                complexData = getComplexDataType( complexDataNode );
307            }
308            if ( null == boundingBoxDataNode && null == complexDataNode && null != literalDataNode ) {
309                literalData = getLiteralInputType( literalDataNode );
310    
311            }
312            int occurs = XMLTools.getNodeAsInt( inputDescriptionNode, "wps:MinimumOccurs/text()",
313                                                nsContext, 1 );
314    
315            return new InputDescription( identifier, title, _abstract, boundingBoxData, complexData,
316                                         literalData, occurs );
317        }
318    
319        @SuppressWarnings("unchecked")
320        private SupportedCRSs getSupportedCRSsType( Element boundingBoxDataNode ) throws XMLParsingException {
321    
322            List<URI> crsList = null;
323    
324            // Get required nodes <wps:CRS>
325            List<Element> crsNodes = XMLTools.getRequiredElements( boundingBoxDataNode, "wps:CRS",
326                                                                nsContext );
327            if ( null != crsNodes && 0 != crsNodes.size() ) {
328                int size = crsNodes.size();
329                crsList = new ArrayList<URI>( size );
330                for ( int i = 0; i < size; i++ ) {
331    
332                    String crs = XMLTools.getNodeAsString( crsNodes.get( i ), "/text()", nsContext,
333                                                           null );
334    
335                    crsList.add( i, buildURIFromString( crs ) );
336                }
337            }
338    
339            // Get required attribute "defaultCRS" from node <wps:BoundingBoxData>
340            URI defaultCRS = buildURIFromString( boundingBoxDataNode.getAttribute( "defaultCRS" ) );
341    
342            return new SupportedCRSs( crsList, defaultCRS );
343    
344        }
345    
346        /**
347         * @param complexDataNode
348         * @return
349         * @throws XMLParsingException
350         */
351        private ComplexData getComplexDataType( Element complexDataNode ) throws XMLParsingException {
352            String defaultEncoding = null;
353            String defaultFormat = null;
354            String defaultSchema = null;
355            List<SupportedComplexData> supportedComplexDataList = null;
356    
357            // Get optional attribute "defaultFormat" from <wps:ComplexData> node
358            String defaultFormatAttribute = complexDataNode.getAttribute( "defaultFormat" );
359            if ( null != defaultFormatAttribute && !"".equals( defaultFormatAttribute ) ) {
360                defaultFormat = defaultFormatAttribute;
361            }
362    
363            // Get optional attribute "defaultEncoding" from <wps:ComplexData> node
364            String defaultEncodingAttribute = complexDataNode.getAttribute( "defaultEncoding" );
365            if ( null != defaultEncodingAttribute && !"".equals( defaultEncodingAttribute ) ) {
366                defaultEncoding = defaultEncodingAttribute;
367            }
368    
369            // Get optional attribute "defaultSchema" from <wps:ComplexData> node
370            String defaultSchemaAttribute = complexDataNode.getAttribute( "defaultSchema" );
371            if ( null != defaultSchemaAttribute && !"".equals( defaultSchemaAttribute ) ) {
372                defaultSchema = defaultSchemaAttribute;
373            }
374    
375            List supportedComplexDataNodes = XMLTools.getNodes( complexDataNode,
376                                                                "wps:SupportedComplexData", nsContext );
377            if ( null != supportedComplexDataNodes && 0 != supportedComplexDataNodes.size() ) {
378                int size = supportedComplexDataNodes.size();
379                supportedComplexDataList = new ArrayList<SupportedComplexData>( size );
380                for ( int i = 0; i < size; i++ ) {
381                    supportedComplexDataList.add(
382                                                  i,
383                                                  getSupportedComplexData( (Element) supportedComplexDataNodes.get( i ) ) );
384                }
385            }
386    
387            return new ComplexData( defaultEncoding, defaultFormat, defaultSchema,
388                                    supportedComplexDataList );
389        }
390    
391        /**
392         * @param element
393         * @return
394         * @throws XMLParsingException
395         */
396        private SupportedComplexData getSupportedComplexData( Element supportedComplexDataNode ) throws XMLParsingException {
397            String encoding = null;
398            String format = null;
399            String schema = null;
400    
401            // Get optional node <wps:Encoding>
402            String wpsEncoding = XMLTools.getNodeAsString( supportedComplexDataNode,
403                                                           "wps:Encoding/text()", nsContext, null );
404            if ( null != wpsEncoding && !"".equals( wpsEncoding ) ) {
405                encoding = wpsEncoding;
406            }
407    
408            // Get optional node <wps:Format>
409            String wpsFormat = XMLTools.getNodeAsString( supportedComplexDataNode, "wps:Format/text()",
410                                                         nsContext, null );
411            if ( null != wpsFormat && !"".equals( wpsFormat ) ) {
412                format = wpsFormat;
413            }
414    
415            // Get optional node <wps:Schema>
416            String wpsSchema = XMLTools.getNodeAsString( supportedComplexDataNode, "wps:Schema/text()",
417                                                         nsContext, null );
418            if ( null != wpsSchema && !"".equals( wpsSchema ) ) {
419                schema = wpsSchema;
420            }
421            return new SupportedComplexData( encoding, format, schema );
422        }
423    
424        /**
425         * @return
426         */
427        private LiteralInput getLiteralInputType( Element literalDataNode ) throws XMLParsingException {
428            OWSMetadata domainMetadataType = null;
429            SupportedUOMs supportedUOMsType = null;
430            OWSAllowedValues allowedValues = null;
431            boolean anyValueAllowed = false;
432            ValueRange defaultValue = null;
433            OWSMetadata valuesReference = null;
434    
435            // Get optional node <ows:DataType>
436            Element dataTypeNode = (Element) XMLTools.getNode( literalDataNode, "ows:DataType",
437                                                               nsContext );
438            if ( null != dataTypeNode ) {
439                domainMetadataType = getDomainMetadataTypeFromContent( dataTypeNode );
440            }
441    
442            // Get optional node <wps:SupportedUOMs>
443            Element supportedUOMsNode = (Element) XMLTools.getNode( literalDataNode,
444                                                                    "wps:SupportedUOMs", nsContext );
445            if ( null != supportedUOMsNode ) {
446                supportedUOMsType = getSupportedUOMs( supportedUOMsNode );
447            }
448    
449            // Get optional node <wps:AllowedValues>
450            Element allowedValuesNode = (Element) XMLTools.getNode( literalDataNode,
451                                                                    "ows:AllowedValues", nsContext );
452            // Get optional node <wps:AnyValue>
453            Element anyValueNode = (Element) XMLTools.getNode( literalDataNode, "ows:AnyValue",
454                                                               nsContext );
455            // Get optional node <wps:ValuesReference>
456            Element valuesReferenceNode = (Element) XMLTools.getNode( literalDataNode,
457                                                                      "ows:ValuesReference", nsContext );
458    
459            if ( null != allowedValuesNode && null == anyValueNode && null == valuesReferenceNode ) {
460                allowedValues = getOWSAllowedValues( allowedValuesNode );
461            } else if ( null == allowedValuesNode && null != anyValueNode
462                        && null == valuesReferenceNode ) {
463                anyValueAllowed = true;
464            } else if ( null == allowedValuesNode && null == anyValueNode
465                        && null != valuesReferenceNode ) {
466                String reference = valuesReferenceNode.getAttributeNS( OWSNS.toString(), "reference" );
467                String value = XMLTools.getNodeAsString( valuesReferenceNode, "/text()", nsContext,
468                                                         null );
469                if ( null != value ) {
470                    URI referenceURI = buildURIFromString( reference );
471                    valuesReference = new OWSMetadata( null, new SimpleLink( referenceURI ), value );
472                }
473            } else {
474                throw new XMLParsingException( "A required data type is missing!" );
475            }
476    
477            // Get optional node <wps:DefaultValue>
478            Element defaultValueNode = (Element) XMLTools.getNode( literalDataNode, "ows:DefaultValue",
479                                                                   nsContext );
480            if ( null != defaultValueNode ) {
481                defaultValue = getOwsRange( defaultValueNode );
482            }
483    
484            return new LiteralInput( domainMetadataType, supportedUOMsType, allowedValues,
485                                     anyValueAllowed, defaultValue, valuesReference );
486        }
487    
488        private URI buildURIFromString( String reference ) throws XMLParsingException {
489            URI referenceURI = null;
490            try {
491                referenceURI = new URI( reference );
492            } catch ( URISyntaxException e ) {
493                String msg = "The URI syntax is malformed. " + e.getMessage();
494                LOG.logError( msg );
495                throw new XMLParsingException( msg, e );
496            }
497            return referenceURI;
498        }
499    
500        private SupportedUOMs getSupportedUOMs( Element supportedUOMsNode ) throws XMLParsingException {
501            List uomNodesList = XMLTools.getNodes( supportedUOMsNode, "ows:UOM", nsContext );
502    
503            List<OWSMetadata> domainMetadataTypeList = null;
504            if ( null != uomNodesList && 0 != uomNodesList.size() ) {
505                int uomNodesListSize = uomNodesList.size();
506                domainMetadataTypeList = new ArrayList<OWSMetadata>( uomNodesListSize );
507                for ( int i = 0; i < uomNodesListSize; i++ ) {
508                    Element nodeListElement = (Element) uomNodesList.get( i );
509    
510                    domainMetadataTypeList.add( i, getDomainMetadataTypeFromAttribute( nodeListElement ) );
511                }
512            }
513            String defaultuom = supportedUOMsNode.getAttribute( "defaultUOM" );
514            URI defaultUOMURI = buildURIFromString( defaultuom );
515            OWSMetadata defaultUOMObject = new OWSMetadata( null, new SimpleLink( defaultUOMURI ), null );
516    
517            return new SupportedUOMs( defaultUOMObject, domainMetadataTypeList );
518        }
519    
520        private OWSMetadata getDomainMetadataTypeFromContent( Element e ) throws XMLParsingException {
521            String owsDataType = XMLTools.getNodeAsString( e, "/text()", nsContext, null );
522            String reference = e.getAttributeNS( OWSNS.toString(), "reference" );
523            URI referenceURI = buildURIFromString( reference );
524            return new OWSMetadata( null, new SimpleLink( referenceURI ), owsDataType );
525        }
526    
527        private OWSMetadata getDomainMetadataTypeFromAttribute( Element e ) throws XMLParsingException {
528            String reference = e.getAttributeNS( OWSNS.toString(), "reference" );
529            URI referenceURI = buildURIFromString( reference );
530    
531            return new OWSMetadata( null, new SimpleLink( referenceURI ), null );
532        }
533    
534        @SuppressWarnings("unchecked")
535        private OWSAllowedValues getOWSAllowedValues( Element e ) throws XMLParsingException {
536            TypedLiteral[] owsValues = null;
537            ValueRange[] valueRanges = null;
538    
539            // gets a Node list of type ows:Value
540            List owsValueNodeList = XMLTools.getNodes( e, "ows:Value", nsContext );
541    
542            if ( null != owsValueNodeList && 0 != owsValueNodeList.size() ) {
543                int size = owsValueNodeList.size();
544                owsValues = new TypedLiteral[size];
545                for ( int i = 0; i < size; i++ ) {
546                    owsValues[i] = ( getOwsValue( (Element) owsValueNodeList.get( i ) ) );
547                }
548            }
549    
550            List owsRangeNodeList = XMLTools.getNodes( e, "ows:Range", nsContext );
551    
552            if ( null != owsRangeNodeList && 0 != owsRangeNodeList.size() ) {
553                int size = owsRangeNodeList.size();
554                valueRanges = new ValueRange[size];
555                for ( int i = 0; i < size; i++ ) {
556                    valueRanges[i] = ( getOwsRange( (Element) owsRangeNodeList.get( i ) ) );
557                }
558            }
559    
560            return new OWSAllowedValues( owsValues, valueRanges );
561        }
562    
563        /**
564         * @param element
565         * @return
566         * @throws XMLParsingException
567         */
568        private ValueRange getOwsRange( Element element ) throws XMLParsingException {
569    
570            TypedLiteral maximum = getOwsValue( (Element) XMLTools.getNode( element,
571                                                                            "ows:MaximumValue",
572                                                                            nsContext ) );
573    
574            TypedLiteral minimum = getOwsValue( (Element) XMLTools.getNode( element,
575                                                                            "ows:MinimumValue",
576                                                                            nsContext ) );
577    
578            Closure rangeClosure = null;
579    
580            String rangeClosureAttribute = element.getAttributeNS( OWSNS.toString(), "rangeClosure" );
581            if ( "closed".equalsIgnoreCase( rangeClosureAttribute ) ) {
582                rangeClosure = new Closure( Closure.CLOSED );
583            } else if ( "open".equalsIgnoreCase( rangeClosureAttribute ) ) {
584                rangeClosure = new Closure( Closure.OPENED );
585            } else if ( "closed-open".equalsIgnoreCase( rangeClosureAttribute ) ) {
586                rangeClosure = new Closure( Closure.CLOSED_OPENED );
587            } else if ( "open-closed".equalsIgnoreCase( rangeClosureAttribute ) ) {
588                rangeClosure = new Closure( Closure.OPENED_CLOSED );
589            } else {
590                throw new XMLParsingException( "Attribute range closure contains invalid value." );
591            }
592    
593            TypedLiteral spacing = null;
594    
595            Element spacingNode = (Element) XMLTools.getNode( element, "ows:Spacing", nsContext );
596            if ( null != spacingNode ) {
597                spacing = getOwsValue( spacingNode );
598            }
599    
600            return new ValueRange( minimum, maximum, spacing, null, null, false, rangeClosure );
601        }
602    
603        /**
604         * @param element
605         * @return
606         * @throws XMLParsingException
607         */
608        private TypedLiteral getOwsValue( Element element ) throws XMLParsingException {
609            String value = XMLTools.getNodeAsString( element, "/text()", nsContext, null );
610            return new TypedLiteral( value, null );
611        }
612    
613        /**
614         * @param element
615         * @return
616         * @throws XMLParsingException
617         */
618        private OutputDescription getOutputDescription( Element outputDescriptionNode ) throws XMLParsingException {
619            Code identifier = getIdentifier( outputDescriptionNode );
620    
621            String title = getTitle( outputDescriptionNode );
622    
623            String _abstract = getAbstract( outputDescriptionNode );
624    
625            Element boundingBoxOutputNode = (Element) XMLTools.getNode( outputDescriptionNode,
626                                                                        "wps:BoundingBoxOutput",
627                                                                        nsContext );
628            Element complexOutputNode = (Element) XMLTools.getNode( outputDescriptionNode,
629                                                                    "wps:ComplexOutput", nsContext );
630            Element literalOutputNode = (Element) XMLTools.getNode( outputDescriptionNode,
631                                                                    "wps:LiteralOutput", nsContext );
632    
633            SupportedCRSs boundingBoxOutput = null;
634            ComplexData complexOutput = null;
635            LiteralOutput literalOutput = null;
636    
637            if ( null != boundingBoxOutputNode && null == complexOutputNode
638                 && null == literalOutputNode ) {
639                boundingBoxOutput = getSupportedCRSsType( boundingBoxOutputNode );
640            } else if ( null == boundingBoxOutputNode && null != complexOutputNode
641                        && null == literalOutputNode ) {
642                complexOutput = getComplexDataType( complexOutputNode );
643            } else if ( null == boundingBoxOutputNode && null == complexOutputNode
644                        && null != literalOutputNode ) {
645                Element dataTypeNode = (Element) XMLTools.getNode( literalOutputNode, "ows:DataType",
646                                                                   nsContext );
647                OWSMetadata domainMetadataType = getDomainMetadataTypeFromContent( dataTypeNode );
648                Element supportedUOMsNode = (Element) XMLTools.getNode( literalOutputNode,
649                                                                        "wps:SupportedUOMs", nsContext );
650                SupportedUOMs supportedUOMsType = null;
651                if ( null != supportedUOMsNode ) {
652                    supportedUOMsType = getSupportedUOMs( supportedUOMsNode );
653                }
654                literalOutput = new LiteralOutput( domainMetadataType, supportedUOMsType );
655            } else {
656                throw new XMLParsingException( "A required data type is missing!" );
657            }
658    
659            return new OutputDescription( identifier, title, _abstract, boundingBoxOutput,
660                                          complexOutput, literalOutput );
661        }
662    
663    }
664    /*********************************************************************
665     <code>
666     Changes to this class. What the people have been up to:
667     $Log$
668     Revision 1.4  2007/02/07 15:01:51  poth
669     not necessary type casts removed
670    
671     Revision 1.3  2006/08/24 06:42:16  poth
672     File header corrected
673    
674     Revision 1.2  2006/07/12 14:46:15  poth
675     comment footer added
676     </code>
677     ********************************************************************** */