    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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    }