001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/ogcwebservices/wps/execute/ExecuteRequest.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    
037    package org.deegree.ogcwebservices.wps.execute;
038    
039    import static org.deegree.ogcbase.CommonNamespaces.OWSNS;
040    
041    import java.net.MalformedURLException;
042    import java.net.URI;
043    import java.net.URISyntaxException;
044    import java.net.URL;
045    import java.util.ArrayList;
046    import java.util.HashMap;
047    import java.util.List;
048    import java.util.Map;
049    
050    import org.deegree.datatypes.Code;
051    import org.deegree.datatypes.values.TypedLiteral;
052    import org.deegree.framework.log.ILogger;
053    import org.deegree.framework.log.LoggerFactory;
054    import org.deegree.framework.xml.NamespaceContext;
055    import org.deegree.framework.xml.XMLParsingException;
056    import org.deegree.framework.xml.XMLTools;
057    import org.deegree.model.crs.CRSFactory;
058    import org.deegree.model.crs.CoordinateSystem;
059    import org.deegree.model.crs.UnknownCRSException;
060    import org.deegree.model.feature.GMLFeatureCollectionDocument;
061    import org.deegree.model.spatialschema.Envelope;
062    import org.deegree.model.spatialschema.GeometryFactory;
063    import org.deegree.ogcbase.CommonNamespaces;
064    import org.deegree.ogcwebservices.InvalidParameterValueException;
065    import org.deegree.ogcwebservices.MissingParameterValueException;
066    import org.deegree.ogcwebservices.OGCWebServiceException;
067    import org.deegree.ogcwebservices.OperationNotSupportedException;
068    import org.deegree.ogcwebservices.wps.WPSRequestBaseType;
069    import org.deegree.ogcwebservices.wps.execute.IOValue.ComplexValueReference;
070    import org.w3c.dom.Element;
071    
072    /**
073     * ExecuteRequest.java
074     *
075     * Created on 09.03.2006. 23:16:00h
076     *
077     * WPS Execute operation request, to execute one identified Process. If a process is to be run multiple times, each run
078     * shall be submitted as a separate Execute request.
079     *
080     *
081     * @author <a href="mailto:christian@kiehle.org">Christian Kiehle</a>
082     * @author <a href="mailto:christian.heier@gmx.de">Christian Heier</a>
083     * @author last edited by: $Author: mschneider $
084     *
085     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
086     */
087    public class ExecuteRequest extends WPSRequestBaseType {
088    
089        /**
090         *
091         */
092        private static final long serialVersionUID = -2943128923230930885L;
093    
094        private static ILogger LOG = LoggerFactory.getLogger( ExecuteRequest.class );
095    
096        private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
097    
098        /**
099         * @param version
100         * @param id
101         * @param vendorSpecificParameter
102         * @param inputs
103         * @param identifier
104         * @param definitions
105         * @param status
106         * @param store
107         */
108        public ExecuteRequest( String version, String id, Map<String, String> vendorSpecificParameter,
109                               ExecuteDataInputs inputs, Code identifier, OutputDefinitions definitions, boolean status,
110                               boolean store ) {
111            super( version, id, vendorSpecificParameter );
112    
113            dataInputs = inputs;
114            this.identifier = identifier;
115            outputDefinitions = definitions;
116            this.status = status;
117            this.store = store;
118        }
119    
120        /**
121         * Identifier of the Process to be executed. This Process identifier shall be as listed in the ProcessOfferings
122         * section of the WPS Capabilities document.
123         */
124        protected Code identifier;
125    
126        /**
127         * List of input (or parameter) values provided to the process, including each of the Inputs needed to execute the
128         * process. It is possible to have no inputs provided only when all the inputs are predetermined fixed resources. In
129         * all other cases, at least one input is required.
130         */
131        protected ExecuteDataInputs dataInputs;
132    
133        /**
134         * List of definitions of the outputs (or parameters) requested from the process. These outputs are not normally
135         * identified, unless the client is specifically requesting a limited subset of outputs, and/or is requesting output
136         * formats and/or schemas and/or encodings different from the defaults and selected from the alternatives identified
137         * in the process description, or wishes to customize the descriptive information about the output.
138         */
139        protected OutputDefinitions outputDefinitions;
140    
141        /**
142         * Specifies if the Execute operation response shall be returned quickly with status information, or not returned
143         * until process execution is complete. This parameter shall not be included unless the corresponding
144         * "statusSupported" parameter is included and is "true" in the ProcessDescription for this process.
145         */
146        protected boolean status;
147    
148        /**
149         * Specifies if the complex valued output(s) of this process should be stored by the process as web-accessible
150         * resources. If store is "true", the server shall store all the complex valued output(s) of the process so that the
151         * client can retrieve them as required. If store is "false", all the complex valued output(s) shall be encoded in
152         * the Execute operation response. This parameter shall not be included unless the corresponding "storeSupported"
153         * parameter is included and is "true" in the ProcessDescription for this process.
154         */
155        protected boolean store;
156    
157        /**
158         * @return Returns the identifier.
159         */
160        public Code getIdentifier() {
161            return identifier;
162        }
163    
164        /**
165         * @return Returns the dataInputs.
166         */
167        public ExecuteDataInputs getDataInputs() {
168            return dataInputs;
169        }
170    
171        /**
172         * @return Returns the outputDefinitions.
173         */
174        public OutputDefinitions getOutputDefinitions() {
175            return outputDefinitions;
176        }
177    
178        /**
179         * @return true if status is set.
180         */
181        public boolean isStatus() {
182            return status;
183        }
184    
185        /**
186         * @return true if can store
187         */
188        public boolean isStore() {
189            return store;
190        }
191    
192        /**
193         *
194         * KVP-encoded transfer of the execute operation request is not supported.
195         *
196         * @see "OGC 05-007r4 Subclause 10.2.2"
197         * @param map
198         * @return the Execute request created from the map.
199         * @throws OGCWebServiceException
200         *
201         */
202        public static ExecuteRequest create( Map<String, String> map )
203                                throws OGCWebServiceException {
204            String msg = "KVP-encoded transfer of the execute operation request is not supported.";
205            LOG.logError( msg );
206            throw new OperationNotSupportedException( msg );
207        }
208    
209        /**
210         *
211         * @param id
212         * @param executeNode
213         * @return the ExcuteRequest wrapper for the xml encoded request.
214         * @throws OGCWebServiceException
215         * @throws MissingParameterValueException
216         * @throws InvalidParameterValueException
217         */
218        public static ExecuteRequest create( String id, Element executeNode )
219                                throws OGCWebServiceException, MissingParameterValueException,
220                                InvalidParameterValueException {
221    
222            // get attribute version from <wps:Execute> Node
223            String version = getVersion( executeNode );
224    
225            // get attribute status from <wps:Execute> Node
226            boolean status = getStatus( executeNode );
227    
228            // get attribute store from <wps:Execute> Node
229            boolean store = getStore( executeNode );
230    
231            Map<String, String> vendorSpecificParameters = null;
232    
233            // get <ows:Identifier> from <wps:Execute> Node
234            Code identifier = getIdentifier( executeNode );
235    
236            // get <wps:DataInputs> from <wps:Execute> Node
237            ExecuteDataInputs dataInputs = getDataInputs( executeNode );
238    
239            // get <wps:OutputDefinitions> from <wps:Execute> Node
240            OutputDefinitions outputDefinitions = getOutputDefinitions( executeNode );
241    
242            return new ExecuteRequest( version, id, vendorSpecificParameters, dataInputs, identifier, outputDefinitions,
243                                       status, store );
244        }
245    
246        /**
247         *
248         * @param executeNode
249         * @return version
250         * @throws InvalidParameterValueException
251         * @throws MissingParameterValueException
252         */
253        private static final String getVersion( Element executeNode )
254                                throws InvalidParameterValueException, MissingParameterValueException {
255            String version = null;
256            try {
257                version = XMLTools.getRequiredAttrValue( "version", null, executeNode );
258            } catch ( XMLParsingException xmlex ) {
259                String msg = "Operation Request does not include parameter value and this server did not declare a default value for that parameter.";
260                LOG.logDebug( msg );
261                throw new MissingParameterValueException( "Version", msg );
262            }
263            if ( "".equals( version ) ) {
264                String msg = "Operation Request contains an invalid parameter value";
265                LOG.logDebug( msg );
266                throw new InvalidParameterValueException( "Version", msg );
267            }
268            if ( !supportedVersion.equals( version ) ) {
269                String msg = "Operation Request contains an invalid parameter value";
270                LOG.logDebug( msg );
271                throw new InvalidParameterValueException( "Version", msg );
272            }
273            return version;
274        }
275    
276        /**
277         *
278         * @param executeNode
279         * @return status
280         * @throws InvalidParameterValueException
281         */
282        private static final boolean getStatus( Element executeNode )
283                                throws InvalidParameterValueException {
284            boolean status = false;
285            String statusString = XMLTools.getAttrValue( executeNode, null, "status", null );
286            if ( null != statusString ) {
287                if ( "true".equalsIgnoreCase( statusString ) || "false".equalsIgnoreCase( statusString ) ) {
288                    status = new Boolean( statusString );
289                } else {
290                    String msg = "Operation Request contains an invalid parameter value";
291                    LOG.logDebug( msg );
292                    throw new InvalidParameterValueException( "status", msg );
293                }
294            }
295            return status;
296        }
297    
298        /**
299         *
300         * @param executeNode
301         * @return store
302         * @throws InvalidParameterValueException
303         */
304        private static final boolean getStore( Element executeNode )
305                                throws InvalidParameterValueException {
306            boolean store = false;
307            String storeString = XMLTools.getAttrValue( executeNode, null, "store", null );
308            if ( null != storeString ) {
309                if ( "true".equalsIgnoreCase( storeString ) || "false".equalsIgnoreCase( storeString ) ) {
310                    store = new Boolean( storeString );
311                } else {
312                    String msg = "Operation Request contains an invalid parameter value";
313                    LOG.logDebug( msg );
314                    throw new InvalidParameterValueException( "store", msg );
315                }
316            }
317            return store;
318        }
319    
320        /**
321         *
322         * @param e
323         * @return identifier
324         * @throws InvalidParameterValueException
325         * @throws MissingParameterValueException
326         */
327        private static Code getIdentifier( Element e )
328                                throws InvalidParameterValueException, MissingParameterValueException {
329            // Get required node <ows:Identifier>
330            String identifierAsString = null;
331    
332            try {
333                identifierAsString = XMLTools.getRequiredNodeAsString( e, "ows:Identifier/text()", nsContext );
334            } catch ( XMLParsingException ex ) {
335                String msg = "Operation Request does not include parameter value and this server did not declare a default value for that parameter.";
336                LOG.logDebug( msg );
337                throw new MissingParameterValueException( "Identifier", msg );
338            }
339    
340            if ( "".equals( identifierAsString ) ) {
341                String msg = "Operation Request contains an invalid parameter value";
342                LOG.logDebug( msg );
343                throw new InvalidParameterValueException( "Identifier", msg );
344            }
345            return new Code( identifierAsString, null );
346        }
347    
348        /**
349         *
350         * @param executeNode
351         * @return dataInputs
352         * @throws MissingParameterValueException
353         * @throws InvalidParameterValueException
354         */
355        @SuppressWarnings("unchecked")
356        private static ExecuteDataInputs getDataInputs( Element executeNode )
357                                throws MissingParameterValueException, InvalidParameterValueException {
358            // Get optional node <DataInputs>
359            ExecuteDataInputs dataInputs = null;
360            try {
361                Element dataInputsNode = (Element) XMLTools.getNode( executeNode, "wps:DataInputs", nsContext );
362    
363                // dataInputsNode may be null, if not null, at least one <Input> has
364                // to be defined
365                if ( null != dataInputsNode ) {
366                    LOG.logInfo( "DataInputs: " + dataInputsNode );
367                    List dataInputNodeList = XMLTools.getNodes( dataInputsNode, "wps:Input", nsContext );
368    
369                    if ( null != dataInputNodeList && 0 != dataInputNodeList.size() ) {
370                        dataInputs = new ExecuteDataInputs();
371                        int size = dataInputNodeList.size();
372                        HashMap inputs = new HashMap<String, IOValue>( size );
373                        for ( int i = 0; i < size; i++ ) {
374                            IOValue ioValue = getIOValue( (Element) dataInputNodeList.get( i ) );
375    
376                            inputs.put( ioValue.getIdentifier().getCode(), ioValue );
377                        }
378                        dataInputs.setInputs( inputs );
379                    } else {
380                        throw new MissingParameterValueException( "Input",
381                                                                  "If DataInputs node provided, at least one input node has to be defined." );
382                    }
383                }
384            } catch ( XMLParsingException ex ) {
385                String msg = "Optional node DataInputs not declared";
386                LOG.logDebug( msg );
387            }
388    
389            return dataInputs;
390        }
391    
392        /**
393         *
394         * @param inputNode
395         * @return IOValue
396         * @throws InvalidParameterValueException
397         * @throws MissingParameterValueException
398         */
399        private static IOValue getIOValue( Element inputNode )
400                                throws InvalidParameterValueException, MissingParameterValueException {
401            Code identifier = getIdentifier( inputNode );
402            String title = getTitle( inputNode );
403            String _abstract = getAbstract( inputNode );
404            Envelope boundingBox = getBoundingBox( inputNode );
405            ComplexValue complexValue = getComplexValue( inputNode );
406            ComplexValueReference complexValueReference = getValueReference( inputNode );
407            TypedLiteral literalValue = getLiteralValue( inputNode );
408    
409            return new IOValue( identifier, title, _abstract, boundingBox, complexValue, complexValueReference,
410                                literalValue );
411        }
412    
413        /**
414         *
415         * @param e
416         * @return title
417         * @throws MissingParameterValueException
418         * @throws InvalidParameterValueException
419         */
420        private static String getTitle( Element e )
421                                throws MissingParameterValueException, InvalidParameterValueException {
422            String title;
423            try {
424                title = XMLTools.getRequiredNodeAsString( e, "ows:Title/text()", nsContext );
425            } catch ( XMLParsingException ex ) {
426                String msg = "Operation Request does not include parameter value and this server did not declare a default value for that parameter.";
427                throw new MissingParameterValueException( "Title", msg );
428            }
429    
430            if ( "".equals( title ) ) {
431                throw new InvalidParameterValueException( "Title", "Operation Request contains an invalid parameter Value" );
432            }
433            return title;
434        }
435    
436        /**
437         *
438         * @param e
439         * @return abstact
440         */
441        private static String getAbstract( Element e ) {
442            String _abstract = null;
443            try {
444                _abstract = XMLTools.getNodeAsString( e, "ows:Abstract/text()", nsContext, null );
445            } catch ( XMLParsingException ex ) {
446                // optional Node
447            }
448            return _abstract;
449        }
450    
451        /**
452         *
453         * @param e
454         * @return boundingBox
455         * @throws MissingParameterValueException
456         * @throws InvalidParameterValueException
457         */
458        private static Envelope getBoundingBox( Element e )
459                                throws MissingParameterValueException, InvalidParameterValueException {
460            Envelope boundingBox = null;
461    
462            try {
463                Element boundingBoxValueNode = (Element) XMLTools.getNode( e, "wps:BoundingBoxValue", nsContext );
464    
465                if ( null != boundingBoxValueNode ) {
466                    double minX = 0;
467                    double minY = 0;
468                    double maxX = 0;
469                    double maxY = 0;
470                    String crsName = null;
471                    String crs = null;
472                    try {
473                        crs = XMLTools.getRequiredNodeAsString( boundingBoxValueNode, "@crs", nsContext );
474                        String lowerCornerValue = XMLTools.getRequiredNodeAsString( boundingBoxValueNode,
475                                                                                    "ows:LowerCorner/text()", nsContext );
476                        String[] lowerCornerValues = lowerCornerValue.split( " " );
477                        if ( lowerCornerValues.length != 2 ) {
478                            throw new InvalidParameterValueException( "lowerCornerNode", "Two parameters are mandatory." );
479                        }
480                        minX = Double.parseDouble( lowerCornerValues[0] );
481                        minY = Double.parseDouble( lowerCornerValues[1] );
482                    } catch ( XMLParsingException ex ) {
483                        throw new MissingParameterValueException(
484                                                                  "LowerCornerNode",
485                                                                  "Operation Request does not include "
486                                                                                          + "parameter value and this server did "
487                                                                                          + "not declare a default value for that "
488                                                                                          + "parameter." );
489                    }
490                    try {
491                        String upperCornerValue = XMLTools.getRequiredNodeAsString( boundingBoxValueNode,
492                                                                                    "ows:UpperCorner/text()", nsContext );
493                        String[] upperCornerValues = upperCornerValue.split( " " );
494                        if ( upperCornerValues.length != 2 ) {
495                            throw new InvalidParameterValueException( "upperCornerNode", "Two parameters are mandatory." );
496                        }
497                        maxX = Double.parseDouble( upperCornerValues[0] );
498                        maxY = Double.parseDouble( upperCornerValues[1] );
499                    } catch ( XMLParsingException ex ) {
500                        throw new MissingParameterValueException(
501                                                                  "LowerCornerNode",
502                                                                  "Operation Request does not include parameter value and this server did not declare a default value for that parameter." );
503                    }
504    
505                    crsName = crs.substring( 16 );
506    
507                    CoordinateSystem cs;
508                    try {
509                        cs = CRSFactory.create( crsName );
510                    } catch ( UnknownCRSException e1 ) {
511                        throw new InvalidParameterValueException( ExecuteRequest.class.getName(), e1.getMessage() );
512                    }
513    
514                    boundingBox = GeometryFactory.createEnvelope( minX, minY, maxX, maxY, cs );
515                }
516            } catch ( XMLParsingException ex ) {
517                // optionalNode
518            }
519            return boundingBox;
520        }
521    
522        /**
523         *
524         * @param e
525         * @return complexValue
526         * @throws InvalidParameterValueException
527         */
528        private static ComplexValue getComplexValue( Element e )
529                                throws InvalidParameterValueException {
530            ComplexValue complexValue = null;
531    
532            try {
533                Element complexValueNode = (Element) XMLTools.getNode( e, "wps:ComplexValue", nsContext );
534                if ( null != complexValueNode ) {
535                    String format = null;
536                    URI encoding = null;
537                    URL schema = null;
538                    Object value = null;
539                    try {
540    
541                        format = complexValueNode.getAttribute( "format" );
542                        if ( null != format ) {
543                            if ( "".equals( format ) ) {
544                                throw new InvalidParameterValueException( "ComplexValue",
545                                                                          "Attribute format must not be empty if provided." );
546    
547                            }
548                        }
549                        String enc = complexValueNode.getAttribute( "encoding" );
550                        if ( null != enc ) {
551                            if ( "".equals( enc ) ) {
552                                throw new InvalidParameterValueException( "ComplexValue",
553                                                                          "Attribute encoding must not be empty if provided." );
554                            }
555                            encoding = new URI( enc );
556                        }
557    
558                        String scheme = complexValueNode.getAttribute( "schema" );
559                        if ( null != scheme ) {
560                            if ( "".equals( scheme ) ) {
561                                throw new InvalidParameterValueException( "ComplexValue",
562                                                                          "Attribute schema must not be empty if provided." );
563                            }
564                            schema = new URL( scheme );
565                        }
566    
567                        /**
568                         * FIXME complexValue may contain any type of data specified by the attributes format, encoding and
569                         * schema dynamically extract the content of this node according to specified format, encoding ,
570                         * schema
571                         *
572                         * @see OGC05-007r4 Table 35. At the moment only a GML FeatureCollection is supported.
573                         *
574                         * does using xmlfragment make more sense??
575                         */
576                        Element complexValueContent = XMLTools.getFirstChildElement( complexValueNode );
577                        if ( null != complexValueContent ) {
578                            try {
579    
580                                GMLFeatureCollectionDocument gmlFeatureCollectionDoc = new GMLFeatureCollectionDocument();
581                                gmlFeatureCollectionDoc.setRootElement( complexValueContent );
582                                value = gmlFeatureCollectionDoc.parse();
583    
584                            } catch ( XMLParsingException ex1 ) {
585                                LOG.logInfo( "Provided content cannot be parsed as featurecollection" );
586                            }
587                        }
588    
589                    } catch ( URISyntaxException uriEx ) {
590                        throw new InvalidParameterValueException( "ComplexValue",
591                                                                  "Operation Request contains an invalid parameter Value" );
592                    } catch ( MalformedURLException mue ) {
593                        throw new InvalidParameterValueException( "ComplexValue",
594                                                                  "Operation Request contains an invalid parameter Value" );
595                    }
596    
597                    complexValue = new ComplexValue( format, encoding, schema, value );
598                }
599    
600            } catch ( XMLParsingException ex ) {
601                // optionalNode
602            }
603    
604            return complexValue;
605    
606        }
607    
608        /**
609         *
610         * @param e
611         * @return complexValueReference
612         * @throws InvalidParameterValueException
613         */
614        private static ComplexValueReference getValueReference( Element e )
615                                throws InvalidParameterValueException {
616            ComplexValueReference complexValueReference = null;
617    
618            Element complexValueReferenceNode;
619            try {
620                complexValueReferenceNode = (Element) XMLTools.getNode( e, "wps:ComplexValueReference", nsContext );
621    
622                if ( null != complexValueReferenceNode ) {
623                    String format = null;
624                    URI encoding = null;
625                    URL schema = null;
626                    URL reference = null;
627    
628                    format = complexValueReferenceNode.getAttribute( "format" );
629                    if ( null != format ) {
630                        if ( "".equals( format ) ) {
631                            throw new InvalidParameterValueException( "ComplexValueReference",
632                                                                      "Attribute format must not be empty if provided." );
633                        }
634                    }
635    
636                    String enc = complexValueReferenceNode.getAttribute( "encoding" );
637                    if ( null != enc ) {
638                        if ( "".equals( enc ) ) {
639                            throw new InvalidParameterValueException( "ComplexValueReference",
640                                                                      "Attribute encoding must not be empty if provided." );
641                        }
642                        try {
643                            encoding = new URI( enc );
644                        } catch ( URISyntaxException e1 ) {
645                            throw new InvalidParameterValueException( "ComplexValueReference",
646                                                                      "Provided content of attribute encoding could not be parsed as URI." );
647                        }
648                    }
649    
650                    String scheme = complexValueReferenceNode.getAttribute( "schema" );
651                    if ( null != scheme ) {
652                        if ( "".equals( scheme ) ) {
653                            throw new InvalidParameterValueException( "ComplexValueReference",
654                                                                      "Attribute schema must not be empty if provided." );
655                        }
656                        try {
657                            schema = new URL( scheme );
658                        } catch ( MalformedURLException e1 ) {
659                            throw new InvalidParameterValueException( "ComplexValueReference",
660                                                                      "Provided content of attribute schema could not be parsed as URL." );
661                        }
662                    }
663    
664                    String referenceString = complexValueReferenceNode.getAttributeNS( OWSNS.toString(), "reference" );
665                    if ( "".equals( referenceString ) ) {
666                        throw new InvalidParameterValueException( "ComplexValueReference",
667                                                                  "Mandatory attibute reference must not be empty." );
668                    }
669                    try {
670                        reference = new URL( referenceString );
671                    } catch ( MalformedURLException e1 ) {
672                        throw new InvalidParameterValueException( "ComplexValueReference",
673                                                                  "Provided content of attribute reference could not be parsed as URL." );
674    
675                    }
676    
677                    complexValueReference = new IOValue.ComplexValueReference( format, encoding, schema, reference );
678                }
679            } catch ( XMLParsingException e1 ) {
680                // optional element
681            }
682    
683            return complexValueReference;
684        }
685    
686        /**
687         *
688         * @param e
689         * @return literalValue
690         * @throws InvalidParameterValueException
691         */
692        private static TypedLiteral getLiteralValue( Element e )
693                                throws InvalidParameterValueException {
694            TypedLiteral literalValue = null;
695    
696            Element literalValueNode;
697            try {
698                literalValueNode = (Element) XMLTools.getNode( e, "wps:LiteralValue", nsContext );
699                if ( null != literalValueNode ) {
700                    String value = null;
701                    URI dataType = null;
702                    URI uom = null;
703                    String dataTypeString = literalValueNode.getAttribute( "dataType" );
704                    if ( null != dataTypeString ) {
705                        if ( "".equals( dataTypeString ) ) {
706                            throw new InvalidParameterValueException( "LiteralValue",
707                                                                      "Attribute data type must not be empty if provided." );
708                        }
709                        try {
710                            dataType = new URI( dataTypeString );
711                        } catch ( URISyntaxException e1 ) {
712                            throw new InvalidParameterValueException( "LiteralValue",
713                                                                      "Provided content of attribute data type could not be parsed as URI." );
714                        }
715                    }
716    
717                    String uomString = literalValueNode.getAttribute( "uom" );
718                    if ( null != uomString ) {
719                        if ( "".equals( uomString ) ) {
720                            throw new InvalidParameterValueException( "LiteralValue",
721                                                                      "Attribute uom must not be empty if provided." );
722                        }
723                    }
724                    try {
725                        uom = new URI( uomString );
726                    } catch ( URISyntaxException e1 ) {
727                        throw new InvalidParameterValueException( "LiteralValue",
728                                                                  "Provided content of attribute uom could not be parsed as URI." );
729                    }
730                    value = XMLTools.getNodeAsString( literalValueNode, "/text()", nsContext, null );
731    
732                    literalValue = new TypedLiteral( value, dataType, uom );
733                }
734    
735            } catch ( XMLParsingException e1 ) {
736                // optional Element
737            }
738    
739            return literalValue;
740        }
741    
742        /**
743         *
744         * @param executeNode
745         * @return outputDefinitions
746         * @throws MissingParameterValueException
747         * @throws InvalidParameterValueException
748         */
749        @SuppressWarnings("unchecked")
750        private static OutputDefinitions getOutputDefinitions( Element executeNode )
751                                throws MissingParameterValueException, InvalidParameterValueException {
752            OutputDefinitions outputDefinitions = null;
753    
754            try {
755                Element outputDefinitionsNode = (Element) XMLTools.getNode( executeNode, "wps:OutputDefinitions", nsContext );
756    
757                if ( null != outputDefinitionsNode ) {
758    
759                    // outputDefinitionsNode may be null, if not null, at least one <Input> has to be defined
760                    LOG.logInfo( "outputDefinitionsNode: " + outputDefinitionsNode );
761                    List outputNodeList = XMLTools.getNodes( outputDefinitionsNode, "wps:Output", nsContext );
762    
763                    if ( null != outputNodeList && 0 != outputNodeList.size() ) {
764                        outputDefinitions = new OutputDefinitions();
765                        int size = outputNodeList.size();
766                        List outputs = new ArrayList<OutputDefinition>( size );
767                        for ( int i = 0; i < size; i++ ) {
768                            outputs.add( i, getOutputDefinition( (Element) outputNodeList.get( i ) ) );
769                        }
770    
771                        outputDefinitions.setOutputDefinitions( outputs );
772                    } else {
773                        throw new MissingParameterValueException( "Output",
774                                                                  "If OutputDefinitions node provided, at least one output node has to be defined." );
775                    }
776                }
777    
778            } catch ( XMLParsingException ex ) {
779                // Optional element
780            }
781    
782            return outputDefinitions;
783        }
784    
785        /**
786         *
787         * @param outputNode
788         * @return outputDefinitions
789         * @throws InvalidParameterValueException
790         * @throws MissingParameterValueException
791         */
792        private static OutputDefinition getOutputDefinition( Element outputNode )
793                                throws InvalidParameterValueException, MissingParameterValueException {
794    
795            Code identifier = getIdentifier( outputNode );
796            String title = getTitle( outputNode );
797            String _abstract = getAbstract( outputNode );
798            String format = null;
799            URI encoding = null;
800            URL schema = null;
801            URI uom = null;
802    
803            format = outputNode.getAttribute( "format" );
804            if ( null != format ) {
805                if ( "".equals( format ) ) {
806                    throw new InvalidParameterValueException( "Output", "Attribute format must not be empty if provided." );
807                }
808            }
809    
810            String enc = outputNode.getAttribute( "encoding" );
811            if ( null != enc ) {
812                if ( "".equals( enc ) ) {
813                    throw new InvalidParameterValueException( "Output", "Attribute encoding must not be empty if provided." );
814                }
815                try {
816                    encoding = new URI( enc );
817                } catch ( URISyntaxException e1 ) {
818                    throw new InvalidParameterValueException( "Output",
819                                                              "Provided content of attribute encoding could not be parsed as URI." );
820                }
821            }
822    
823            String scheme = outputNode.getAttribute( "schema" );
824            if ( null != scheme ) {
825                if ( "".equals( scheme ) ) {
826                    throw new InvalidParameterValueException( "Output", "Attribute schema must not be empty if provided." );
827                }
828                try {
829                    schema = new URL( scheme );
830                } catch ( MalformedURLException e1 ) {
831                    throw new InvalidParameterValueException( "Output",
832                                                              "Provided content of attribute schema could not be parsed as URL." );
833                }
834            }
835    
836            String uomString = outputNode.getAttribute( "uom" );
837            if ( null != uomString ) {
838                if ( "".equals( uomString ) ) {
839                    throw new InvalidParameterValueException( "Output", "Attribute uom must not be empty if provided." );
840                }
841            }
842            try {
843                uom = new URI( uomString );
844            } catch ( URISyntaxException e1 ) {
845                throw new InvalidParameterValueException( "Output",
846                                                          "Provided content of attribute uom could not be parsed as URI." );
847            }
848    
849            return new OutputDefinition( identifier, title, _abstract, encoding, format, schema, uom );
850        }
851    
852    }