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