001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/wps/XMLFactory.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2005 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/exse/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstraße 19
030     53177 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041    
042     ---------------------------------------------------------------------------*/
043    package org.deegree.ogcwebservices.wps;
044    
045    import static org.deegree.ogcbase.CommonNamespaces.WPSNS;
046    
047    import java.io.ByteArrayOutputStream;
048    import java.io.IOException;
049    import java.io.StringReader;
050    import java.io.UnsupportedEncodingException;
051    import java.net.URI;
052    import java.net.URL;
053    import java.net.URLEncoder;
054    import java.util.Iterator;
055    import java.util.List;
056    import java.util.Map;
057    
058    import org.deegree.datatypes.Code;
059    import org.deegree.datatypes.values.TypedLiteral;
060    import org.deegree.datatypes.values.ValueRange;
061    import org.deegree.framework.util.CharsetUtils;
062    import org.deegree.framework.xml.XMLFragment;
063    import org.deegree.framework.xml.XMLTools;
064    import org.deegree.model.feature.FeatureCollection;
065    import org.deegree.model.feature.FeatureException;
066    import org.deegree.model.feature.GMLFeatureAdapter;
067    import org.deegree.model.spatialschema.Envelope;
068    import org.deegree.model.spatialschema.Position;
069    import org.deegree.ogcwebservices.ExceptionReport;
070    import org.deegree.ogcwebservices.MetadataType;
071    import org.deegree.ogcwebservices.OGCWebServiceException;
072    import org.deegree.ogcwebservices.getcapabilities.Contents;
073    import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
074    import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
075    import org.deegree.ogcwebservices.getcapabilities.ServiceIdentification;
076    import org.deegree.ogcwebservices.getcapabilities.ServiceProvider;
077    import org.deegree.ogcwebservices.wps.capabilities.ProcessOfferings;
078    import org.deegree.ogcwebservices.wps.capabilities.WPSCapabilities;
079    import org.deegree.ogcwebservices.wps.capabilities.WPSCapabilitiesDocument;
080    import org.deegree.ogcwebservices.wps.describeprocess.ComplexData;
081    import org.deegree.ogcwebservices.wps.describeprocess.InputDescription;
082    import org.deegree.ogcwebservices.wps.describeprocess.LiteralInput;
083    import org.deegree.ogcwebservices.wps.describeprocess.LiteralOutput;
084    import org.deegree.ogcwebservices.wps.describeprocess.OutputDescription;
085    import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescription;
086    import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescriptions;
087    import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescriptionsDocument;
088    import org.deegree.ogcwebservices.wps.describeprocess.SupportedCRSs;
089    import org.deegree.ogcwebservices.wps.describeprocess.SupportedComplexData;
090    import org.deegree.ogcwebservices.wps.describeprocess.SupportedUOMs;
091    import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescription.DataInputs;
092    import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescription.ProcessOutputs;
093    import org.deegree.ogcwebservices.wps.execute.ComplexValue;
094    import org.deegree.ogcwebservices.wps.execute.ExecuteDataInputs;
095    import org.deegree.ogcwebservices.wps.execute.ExecuteResponse;
096    import org.deegree.ogcwebservices.wps.execute.ExecuteResponseDocument;
097    import org.deegree.ogcwebservices.wps.execute.IOValue;
098    import org.deegree.ogcwebservices.wps.execute.OutputDefinition;
099    import org.deegree.ogcwebservices.wps.execute.OutputDefinitions;
100    import org.deegree.ogcwebservices.wps.execute.ProcessFailed;
101    import org.deegree.ogcwebservices.wps.execute.ProcessStarted;
102    import org.deegree.ogcwebservices.wps.execute.Status;
103    import org.deegree.ogcwebservices.wps.execute.IOValue.ComplexValueReference;
104    import org.deegree.owscommon.OWSMetadata;
105    import org.deegree.owscommon.com110.OWSAllowedValues;
106    import org.w3c.dom.Document;
107    import org.w3c.dom.Element;
108    import org.w3c.dom.Node;
109    import org.xml.sax.SAXException;
110    
111    /**
112     * XMLFactory.java
113     * 
114     * Created on 08.03.2006. 23:28:46h
115     * 
116     * @author <a href="mailto:christian@kiehle.org">Christian Kiehle</a>
117     * @author <a href="mailto:christian.heier@gmx.de">Christian Heier</a>
118     * 
119     * @version 1.0.
120     * 
121     * @since 2.0
122     */
123    public class XMLFactory extends org.deegree.owscommon.XMLFactory {
124    
125        /**
126         * 
127         * @param capabilities
128         * @return
129         * @throws InvalidCapabilitiesException
130         * @throws IOException
131         */
132        public static WPSCapabilitiesDocument export( WPSCapabilities capabilities )
133                                throws IOException {
134            LOG.entering();
135            WPSCapabilitiesDocument capabilitiesDocument = new WPSCapabilitiesDocument();
136    
137            try {
138                capabilitiesDocument.createEmptyDocument();
139                Element root = capabilitiesDocument.getRootElement();
140    
141                ServiceIdentification serviceIdentification = capabilities.getServiceIdentification();
142                if ( serviceIdentification != null ) {
143                    appendServiceIdentification( root, serviceIdentification );
144                }
145    
146                ServiceProvider serviceProvider = capabilities.getServiceProvider();
147                if ( serviceProvider != null ) {
148                    appendServiceProvider( root, capabilities.getServiceProvider() );
149                }
150    
151                OperationsMetadata operationsMetadata = capabilities.getOperationsMetadata();
152                if ( operationsMetadata != null ) {
153                    appendOperationsMetadata( root, operationsMetadata );
154                }
155                Contents contents = capabilities.getContents();
156                if ( contents != null ) {
157                    // appendContents(root, contents);
158                }
159                ProcessOfferings processOfferings = capabilities.getProcessOfferings();
160                if ( null != processOfferings ) {
161                    appendProcessOfferings( root, processOfferings );
162                }
163    
164            } catch ( SAXException e ) {
165                LOG.logError( e.getMessage(), e );
166            }
167            LOG.exiting();
168            return capabilitiesDocument;
169        }
170    
171        /**
172         * Appends the DOM representation of the <code>wps:ProcessOfferings</code>-
173         * section to the passed <code>Element</code>.
174         * 
175         * @param root
176         * @param processOfferings
177         */
178        private static void appendProcessOfferings( Element root, ProcessOfferings processOfferings ) {
179            LOG.entering();
180            // Add a <wps:ProcessOfferings>node to the <wps:Capabilities> node
181            Element processOfferingsNode = XMLTools.appendElement( root, WPSNS, "wps:ProcessOfferings",
182                                                                   null );
183            // Add <wps:Process> nodes to the <wps:ProcessOfferings> node
184            List<ProcessBrief> processBriefTypeList = processOfferings.getProcessBriefTypesList();
185            if ( null != processBriefTypeList && 0 != processBriefTypeList.size() ) {
186                int size = processBriefTypeList.size();
187                for ( int i = 0; i < size; i++ ) {
188                    appendProcessBriefType( processOfferingsNode, processBriefTypeList.get( i ) );
189                }
190            }
191    
192            LOG.exiting();
193        }
194    
195        /**
196         * Appends the DOM representation of the <code>ProcessBriefType</code>
197         * instance to the passed <code>Element</code>.
198         * 
199         * @param processOfferingsNode
200         * @param processBriefType
201         */
202        private static void appendProcessBriefType( Element processOfferingsNode,
203                                                   ProcessBrief processBriefType ) {
204    
205            // Add a <wps:Process> node to the <wps:ProcessOfferings> node
206            Element processBriefTypeNode = XMLTools.appendElement( processOfferingsNode, WPSNS,
207                                                                   "wps:Process" );
208            // Add optional attribute "processVersion" to <wps:Process> node if
209            // present
210            String processVersion = processBriefType.getProcessVersion();
211            if ( null != processVersion && !"".equals( processVersion ) ) {
212                processBriefTypeNode.setAttribute( "processVersion", processVersion );
213            }
214    
215            // Add mandatory node <ows:Identifier>
216            Code identifier = processBriefType.getIdentifier();
217            if ( null != identifier ) {
218                appendIdentifier( processBriefTypeNode, identifier );
219            } else {
220                LOG.logError( "identifier is null." );
221            }
222    
223            // Add mandatory node <ows:Title>
224            String title = processBriefType.getTitle();
225            if ( null != title ) {
226                appendTitle( processBriefTypeNode, title );
227            } else {
228                LOG.logError( "title is null." );
229            }
230    
231            // Add optional node <ows:Abstract/>
232    
233            String _abstract = processBriefType.getAbstract();
234            if ( null != _abstract ) {
235                appendAbstract( processBriefTypeNode, _abstract );
236            }
237    
238            // Add optional nodes <ows:Metadata/>
239            List<MetadataType> metaDataTypeList = processBriefType.getMetadata();
240            if ( null != metaDataTypeList && 0 != metaDataTypeList.size() ) {
241                int size = metaDataTypeList.size();
242                for ( int i = 0; i < size; i++ ) {
243                    appendMetaDataType( processBriefTypeNode, metaDataTypeList.get( i ) );
244                }
245            }
246            LOG.exiting();
247        }
248    
249        /**
250         * 
251         * @param e
252         * @param identifier
253         */
254        private static void appendIdentifier( Element e, Code identifier ) {
255    
256            String identifierString = identifier.getCode();
257    
258            if ( null != identifierString && !"".equals( identifierString ) ) {
259                XMLTools.appendElement( e, OWSNS, "ows:Identifier", identifierString );
260            } else {
261                LOG.logError( "identifier is empty." );
262            }
263            LOG.exiting();
264        }
265    
266        /**
267         * 
268         * @param e
269         * @param title
270         */
271        private static void appendTitle( Element e, String title ) {
272    
273            if ( !"".equals( title ) ) {
274                XMLTools.appendElement( e, OWSNS, "ows:Title", title );
275            } else {
276                LOG.logError( "title is empty." );
277            }
278            LOG.exiting();
279        }
280    
281        /**
282         * Appends the DOM representation of the <code>MetadataType</code>
283         * instance to the passed <code>Element</code>.
284         * 
285         * @param e
286         * @param metaDataType
287         */
288        private static void appendMetaDataType( Element e, MetadataType metaDataType ) {
289            LOG.entering();
290            // Add optional node <ows:Metadata>
291            String metadataTypeValue = metaDataType.value;
292            if ( null != metadataTypeValue && !"".equals( metadataTypeValue ) ) {
293                Element metadataNode = XMLTools.appendElement( e, OWSNS, "ows:Metadata" );
294                metadataNode.setAttributeNS( XLNNS.toString(), "xlink:title", metadataTypeValue );
295            }
296            LOG.exiting();
297        }
298    
299        /**
300         * 
301         * @param processDescriptions
302         * @return
303         * @throws InvalidCapabilitiesException
304         * @throws IOException
305         */
306        public static ProcessDescriptionsDocument export( ProcessDescriptions processDescriptions )
307                                throws IOException {
308            ProcessDescriptionsDocument processDescriptionsDocument = new ProcessDescriptionsDocument();
309            try {
310                processDescriptionsDocument.createEmptyDocument();
311                Element root = processDescriptionsDocument.getRootElement();
312                List<ProcessDescription> processDescriptionList = processDescriptions.getProcessDescription();
313                if ( null != processDescriptionList ) {
314                    int processDescriptionListSize = processDescriptionList.size();
315                    for ( int i = 0; i < processDescriptionListSize; i++ ) {
316                        ProcessDescription processDescription = processDescriptionList.get( i );
317                        appendProcessDescription( root, processDescription );
318                    }
319                }
320            } catch ( SAXException sex ) {
321                LOG.logError( sex.getMessage(), sex );
322            }
323            LOG.exiting();
324            return processDescriptionsDocument;
325        }
326    
327        /**
328         * Appends the DOM representation of the <code>ProcessDescription</code>
329         * instance to the passed <code>Element</code>..
330         * 
331         * @param root
332         * @param processDescription
333         */
334        private static void appendProcessDescription( Element root,
335                                                     ProcessDescription processDescription ) {
336            LOG.entering();
337    
338            // Add a <wps:ProcessDescription> node to the <wps:ProcessDescriptions>
339            // node
340            Element processDescriptionNode = XMLTools.appendElement( root, WPSNS,
341                                                                     "wps:ProcessDescription", null );
342    
343            String statusSupported = Boolean.toString( processDescription.isStatusSupported() );
344            processDescriptionNode.setAttribute( "statusSupported", statusSupported );
345    
346            String storeSupported = Boolean.toString( processDescription.isStoreSupported() );
347            processDescriptionNode.setAttribute( "storeSupported", storeSupported );
348    
349            String processVersion = processDescription.getProcessVersion();
350            processDescriptionNode.setAttribute( "processVersion", processVersion );
351    
352            Code identifier = processDescription.getIdentifier();
353            if ( null != identifier ) {
354                appendIdentifier( processDescriptionNode, identifier );
355            } else {
356                LOG.logError( "Identifier is null." );
357            }
358    
359            String title = processDescription.getTitle();
360            if ( null != title ) {
361                appendTitle( processDescriptionNode, title );
362            } else {
363                LOG.logError( "title is null." );
364            }
365    
366            String _abstract = processDescription.getAbstract();
367            if ( null != _abstract ) {
368                appendAbstract( processDescriptionNode, _abstract );
369            }
370    
371            Element metaDataTypeNode = null;
372    
373            MetadataType metadataType = null;
374            List<MetadataType> metaDataTypeList = processDescription.getMetadata();
375            int metaDataTypeListSize = metaDataTypeList.size();
376            for ( int i = 0; i < metaDataTypeListSize; i++ ) {
377                metadataType = metaDataTypeList.get( i );
378                metaDataTypeNode = XMLTools.appendElement( processDescriptionNode, OWSNS,
379                                                           "ows:Metadata" );
380                metaDataTypeNode.setAttributeNS( XLNNS.toString(), "xlink:title", metadataType.value );
381            }
382    
383            DataInputs dataInputs = processDescription.getDataInputs();
384            appendDataInputs( processDescriptionNode, dataInputs );
385    
386            ProcessOutputs processOutputs = processDescription.getProcessOutputs();
387            appendProcessOutputs( processDescriptionNode, processOutputs );
388    
389            LOG.exiting();
390        }
391    
392        /**
393         * 
394         * @param e
395         * @param _abstract
396         */
397        private static void appendAbstract( Element e, String _abstract ) {
398            if ( !"".equals( _abstract ) ) {
399                XMLTools.appendElement( e, OWSNS, "ows:Abstract", _abstract );
400            } else {
401                LOG.logError( "abstract is empty." );
402            }
403            LOG.exiting();
404        }
405    
406        /**
407         * 
408         * @param processDescriptionNode
409         * @param dataInputs
410         */
411        private static void appendDataInputs( Element processDescriptionNode, DataInputs dataInputs ) {
412            LOG.entering();
413            // Add a <wps:DataInputs> node to the <wps:ProcessDescription> node
414            Element dataInputsNode = XMLTools.appendElement( processDescriptionNode, WPSNS,
415                                                             "wps:DataInputs", null );
416            if ( null != dataInputs ) {
417                List<InputDescription> dataInputsList = dataInputs.getInputDescriptions();
418                InputDescription inputDescription = null;
419                int dataInputListSize = dataInputsList.size();
420                for ( int i = 0; i < dataInputListSize; i++ ) {
421                    inputDescription = dataInputsList.get( i );
422                    appendDataInput( dataInputsNode, inputDescription );
423                }
424            }
425            LOG.exiting();
426        }
427    
428        /**
429         * 
430         * @param dataInputsNode
431         * @param inputDescription
432         */
433        private static void appendDataInput( Element dataInputsNode, InputDescription inputDescription ) {
434            LOG.entering();
435            // Add a <wps:DataInput> node to the <wps:DataInputs> node
436            Element inputNode = XMLTools.appendElement( dataInputsNode, WPSNS, "wps:Input", null );
437    
438            if ( null != inputNode ) {
439    
440                Code identifier = inputDescription.getIdentifier();
441                if ( null != identifier ) {
442                    appendIdentifier( inputNode, identifier );
443                } else {
444                    LOG.logError( "identifier is null." );
445                }
446    
447                String title = inputDescription.getTitle();
448                if ( null != title ) {
449                    appendTitle( inputNode, title );
450                } else {
451                    LOG.logError( "title is null." );
452                }
453    
454                String _abstract = inputDescription.getAbstract();
455                if ( null != _abstract ) {
456                    appendAbstract( inputNode, _abstract );
457                }
458    
459                try {
460    
461                    SupportedCRSs supportedCRSs = inputDescription.getBoundingBoxData();
462                    ComplexData complexData = inputDescription.getComplexData();
463                    LiteralInput literalInput = inputDescription.getLiteralData();
464    
465                    if ( null != supportedCRSs ) {
466                        appendBoundingBoxData( inputNode, supportedCRSs );
467                    } else if ( null != complexData ) {
468                        appendComplexData( inputNode, complexData );
469                    } else if ( null != literalInput ) {
470                        appendLiteralInput( inputNode, literalInput );
471                    } else {
472                        LOG.logError( "a required datatype description is missing." );
473                    }
474    
475                } catch ( Exception e ) {
476                    LOG.logError( e.getMessage(), e );
477                }
478    
479                XMLTools.appendElement( inputNode, WPSNS, "wps:MinimumOccurs",
480                                        String.valueOf( inputDescription.getMinimumOccurs() ) );
481            }
482            LOG.exiting();
483        }
484    
485        /**
486         * 
487         * @param root
488         * @param processOutputs
489         */
490        private static void appendProcessOutputs( Element root, ProcessOutputs processOutputs ) {
491            LOG.entering();
492            if ( null != processOutputs ) {
493                // Add a <wps:ProcessOutputs> node to the <wps:ProcessDescription>
494                // node
495                Element processOutputsNode = XMLTools.appendElement( root, WPSNS, "wps:ProcessOutputs",
496                                                                     null );
497                OutputDescription outputDescription = null;
498                List<OutputDescription> outputDescriptionList = processOutputs.getOutput();
499                int outputDescriptionListSize = outputDescriptionList.size();
500                for ( int i = 0; i < outputDescriptionListSize; i++ ) {
501                    outputDescription = outputDescriptionList.get( i );
502                    appendOutputDescription( processOutputsNode, outputDescription );
503                }
504            }
505            LOG.exiting();
506        }
507    
508        /**
509         * 
510         * @param processOutputsNode
511         * @param outputDescription
512         */
513        private static void appendOutputDescription( Element processOutputsNode,
514                                                    OutputDescription outputDescription ) {
515            LOG.entering();
516            if ( null != outputDescription ) {
517    
518                Element outputNode = XMLTools.appendElement( processOutputsNode, WPSNS, "wps:Output",
519                                                             null );
520    
521                Code identifier = outputDescription.getIdentifier();
522                if ( null != identifier ) {
523                    appendIdentifier( outputNode, identifier );
524                } else {
525                    LOG.logError( "identifier is null." );
526                }
527    
528                String title = outputDescription.getTitle();
529                if ( null != title ) {
530                    appendTitle( outputNode, title );
531                } else {
532                    LOG.logError( "title is null." );
533                }
534    
535                String _abstract = outputDescription.getAbstract();
536                if ( null != _abstract ) {
537                    appendAbstract( outputNode, _abstract );
538                }
539    
540                SupportedCRSs supportedCRSs = outputDescription.getBoundingBoxOutput();
541                ComplexData complexData = outputDescription.getComplexOutput();
542                LiteralOutput literalOutput = outputDescription.getLiteralOutput();
543    
544                if ( null != supportedCRSs ) {
545                    appendBoundingBoxOutput( outputNode, supportedCRSs );
546                } else if ( null != complexData ) {
547                    appendComplexOutput( outputNode, complexData );
548                } else if ( null != literalOutput ) {
549                    appendLiteralOutput( outputNode, literalOutput );
550                } else {
551                    LOG.logError( "a required output datatype description is missing." );
552                }
553            }
554            LOG.exiting();
555        }
556    
557        /**
558         * 
559         * @param outputNode
560         * @param complexData
561         */
562        private static void appendComplexOutput( Element outputNode, ComplexData complexData ) {
563    
564            LOG.entering();
565            String defaultEncoding = complexData.getDefaultEncoding();
566            String defaultFormat = complexData.getDefaultFormat();
567            String defaultSchema = complexData.getDefaultSchema();
568            Element complexDataNode = XMLTools.appendElement( outputNode, WPSNS, "wps:ComplexOutput",
569                                                              null );
570    
571            if ( null != defaultFormat && !"".equals( defaultFormat ) ) {
572                complexDataNode.setAttribute( "defaultFormat", defaultFormat );
573            }
574            if ( null != defaultEncoding && !"".equals( defaultEncoding ) ) {
575                complexDataNode.setAttribute( "defaultEncoding", defaultEncoding );
576            }
577            if ( null != defaultSchema && !"".equals( defaultSchema ) ) {
578                complexDataNode.setAttribute( "defaultSchema", defaultSchema );
579            }
580    
581            List<SupportedComplexData> supportedComplexDataList = complexData.getSupportedComplexData();
582            int supporteComplexDataListSize = supportedComplexDataList.size();
583            for ( int i = 0; i < supporteComplexDataListSize; i++ ) {
584                appendSupportedComplexData( complexDataNode, supportedComplexDataList.get( i ) );
585            }
586            LOG.exiting();
587        }
588    
589        /**
590         * 
591         * @param outputNode
592         * @param supportedCRSs
593         */
594        private static void appendBoundingBoxOutput( Element outputNode, SupportedCRSs supportedCRSs ) {
595            LOG.entering();
596            URI defaultCrs = supportedCRSs.getDefaultCRS();
597            Element defaultCRSs = XMLTools.appendElement( outputNode, WPSNS, "wps:BoundingBoxOutput",
598                                                          null );
599            defaultCRSs.setAttribute( "defaultCRS", defaultCrs.toString() );
600    
601            List<URI> crsList = supportedCRSs.getCRS();
602            int crsListSize = crsList.size();
603            for ( int i = 0; i < crsListSize; i++ ) {
604                URI uri = crsList.get( i );
605                XMLTools.appendElement( defaultCRSs, WPSNS, "wps:CRS", uri.toString() );
606            }
607            LOG.exiting();
608        }
609    
610        /**
611         * 
612         * @param outputNode
613         * @param literalOutput
614         */
615        private static void appendLiteralOutput( Element outputNode, LiteralOutput literalOutput ) {
616            LOG.entering();
617            Element literalOutputNode = XMLTools.appendElement( outputNode, WPSNS, "wps:LiteralOutput",
618                                                                null );
619            Element owsDataType = XMLTools.appendElement( literalOutputNode, OWSNS, "ows:DataType",
620                                                          literalOutput.getDataType().getName() );
621            owsDataType.setAttribute( "ows:reference",
622                                      literalOutput.getDataType().getLink().getHref().toString() );
623            Element supportedUOMsNode = XMLTools.appendElement( literalOutputNode, WPSNS,
624                                                                "wps:SupportedUOMs", null );
625    
626            supportedUOMsNode.setAttribute(
627                                            "defaultUOM",
628                                            literalOutput.getSupportedUOMs().getDefaultUOM().getLink().getHref().toString() );
629    
630            List<OWSMetadata> supportedUOMs = literalOutput.getSupportedUOMs().getUOM();
631            int size = supportedUOMs.size();
632            for ( int i = 0; i < size; i++ ) {
633                OWSMetadata uom = supportedUOMs.get( i );
634                Element uomNode = XMLTools.appendElement( supportedUOMsNode, OWSNS, "ows:UOM", null );
635                uomNode.setAttribute( "ows:reference", uom.getLink().getHref().toString() );
636            }
637            LOG.exiting();
638        }
639    
640        /**
641         * 
642         * @param inputNode
643         * @param complexData
644         */
645        private static void appendComplexData( Element inputNode, ComplexData complexData ) {
646            LOG.entering();
647            String defaultEncoding = complexData.getDefaultEncoding();
648            String defaultFormat = complexData.getDefaultFormat();
649            String defaultSchema = complexData.getDefaultSchema();
650            Element complexDataNode = XMLTools.appendElement( inputNode, WPSNS, "wps:ComplexData", null );
651    
652            if ( null != defaultFormat && !"".equals( defaultFormat ) ) {
653                complexDataNode.setAttribute( "defaultFormat", defaultFormat );
654            }
655            if ( null != defaultEncoding && !"".equals( defaultEncoding ) ) {
656                complexDataNode.setAttribute( "defaultEncoding", defaultEncoding );
657            }
658            if ( null != defaultSchema && !"".equals( defaultSchema ) ) {
659                complexDataNode.setAttribute( "defaultSchema", defaultSchema );
660            }
661    
662            List<SupportedComplexData> supportedComplexDataList = complexData.getSupportedComplexData();
663            int supporteComplexDataListSize = supportedComplexDataList.size();
664            for ( int i = 0; i < supporteComplexDataListSize; i++ ) {
665                appendSupportedComplexData( complexDataNode, supportedComplexDataList.get( i ) );
666            }
667            LOG.exiting();
668        }
669    
670        /**
671         * 
672         * @param complexDataNode
673         * @param supportedComplexData
674         */
675        private static void appendSupportedComplexData( Element complexDataNode,
676                                                       SupportedComplexData supportedComplexData ) {
677            LOG.entering();
678    
679            Element supportedComplexDataNode = XMLTools.appendElement( complexDataNode, WPSNS,
680                                                                       "wps:SupportedComplexData", null );
681    
682            XMLTools.appendElement( supportedComplexDataNode, WPSNS, "wps:Format",
683                                    supportedComplexData.getFormat() );
684    
685            XMLTools.appendElement( supportedComplexDataNode, WPSNS, "wps:Encoding",
686                                    supportedComplexData.getEncoding() );
687    
688            XMLTools.appendElement( supportedComplexDataNode, WPSNS, "wps:Schema",
689                                    supportedComplexData.getSchema() );
690    
691            LOG.exiting();
692        }
693    
694        /**
695         * 
696         * @param inputNode
697         * @param literalInput
698         */
699        private static void appendLiteralInput( Element inputNode, LiteralInput literalInput ) {
700            LOG.entering();
701            Element literalDataNode = XMLTools.appendElement( inputNode, WPSNS, "wps:LiteralData", null );
702            Element owsDataType = XMLTools.appendElement( literalDataNode, OWSNS, "ows:DataType",
703                                                          literalInput.getDataType().getName() );
704            owsDataType.setAttribute( "ows:reference",
705                                      literalInput.getDataType().getLink().getHref().toString() );
706            appendLiteralInputTypes( literalDataNode, literalInput );
707    
708            LOG.exiting();
709        }
710    
711        /**
712         * 
713         * @param literalDataNode
714         * @param literalInput
715         */
716        private static void appendLiteralInputTypes( Element literalDataNode, LiteralInput literalInput ) {
717            LOG.entering();
718            Element supportedUOMsNode = XMLTools.appendElement( literalDataNode, WPSNS,
719                                                                "wps:SupportedUOMs", null );
720    
721            SupportedUOMs supportedUOMs = literalInput.getSupportedUOMs();
722            if ( null != supportedUOMs ) {
723    
724                OWSMetadata defaultUOM = literalInput.getSupportedUOMs().getDefaultUOM();
725                if ( null != defaultUOM ) {
726                    supportedUOMsNode.setAttribute(
727                                                    "defaultUOM",
728                                                    literalInput.getSupportedUOMs().getDefaultUOM().getLink().getHref().toString() );
729                }
730    
731                List<OWSMetadata> supportedUOMsList = literalInput.getSupportedUOMs().getUOM();
732                int size = supportedUOMsList.size();
733                for ( int i = 0; i < size; i++ ) {
734                    OWSMetadata uom = supportedUOMsList.get( i );
735                    Element uomNode = XMLTools.appendElement( supportedUOMsNode, OWSNS, "ows:UOM", null );
736                    uomNode.setAttribute( "ows:reference", uom.getLink().getHref().toString() );
737                }
738            }
739    
740            // append <ows:AllowedValues> on <LiteralData>
741            OWSAllowedValues owsAllowedValues = literalInput.getAllowedValues();
742            if ( null != owsAllowedValues ) {
743                Element allowedValuesNode = XMLTools.appendElement( literalDataNode, OWSNS,
744                                                                    "ows:AllowedValues", null );
745                TypedLiteral[] typedLiteralArray = owsAllowedValues.getOwsValues();
746                if ( null != typedLiteralArray ) {
747                    for ( int i = 0; i < typedLiteralArray.length; i++ ) {
748                        // append <ows:Value/> on <ows:AllowedValues>
749                        XMLTools.appendElement( allowedValuesNode, OWSNS, "ows:Value",
750                                                typedLiteralArray[i].getValue() );
751                    }
752                }
753                // append <ows:Range> on <ows:AllowedValues>
754                ValueRange[] valueRangeArray = owsAllowedValues.getValueRanges();
755                if ( null != valueRangeArray ) {
756                    for ( int i = 0; i < valueRangeArray.length; i++ ) {
757                        Element owsRangeNode = XMLTools.appendElement( allowedValuesNode, OWSNS,
758                                                                       "ows:Range" );
759                        String closure = valueRangeArray[i].getClosure().value;
760                        if ( null != closure ) {
761                            owsRangeNode.setAttribute( "ows:rangeClosure", closure );
762                        }
763                        String minimumValue = valueRangeArray[i].getMin().getValue();
764                        if ( null != minimumValue ) {
765                            XMLTools.appendElement( owsRangeNode, OWSNS, "ows:MinimumValue",
766                                                    minimumValue );
767                        }
768                        String maximumValue = valueRangeArray[i].getMax().getValue();
769                        if ( null != maximumValue ) {
770                            XMLTools.appendElement( owsRangeNode, OWSNS, "ows:MaximumValue",
771                                                    maximumValue );
772                        }
773                        TypedLiteral typedLiteralSpacing = valueRangeArray[i].getSpacing();
774                        if ( null != typedLiteralSpacing ) {
775                            String spacing = typedLiteralSpacing.getValue();
776                            if ( null != spacing ) {
777                                XMLTools.appendElement( owsRangeNode, OWSNS, "ows:Spacing", spacing );
778                            }
779                        }
780    
781                    }
782                }
783            }
784    
785            // append <ows:AnyValue> on <LiteralData>
786            boolean anyValueAllowed = literalInput.getAnyValue();
787            if ( false != anyValueAllowed ) {
788                XMLTools.appendElement( literalDataNode, OWSNS, "ows:AnyValue" );
789            }
790    
791            // append <ows:ValuesReference> on <LiteralData>
792            OWSMetadata owsValuesReference = literalInput.getValuesReference();
793            if ( null != owsValuesReference ) {
794                Element valuesReference = XMLTools.appendElement( literalDataNode, OWSNS,
795                                                                  "ows:ValuesReference",
796                                                                  owsValuesReference.getName() );
797                String reference = owsValuesReference.getLink().getHref().toString();
798                if ( null != reference && !"".equals( reference ) ) {
799                    valuesReference.setAttribute( "ows:reference", reference );
800                }
801            }
802    
803            // append <ows:DefaultValue> on <LiteralData>
804            ValueRange defaultValue = literalInput.getDefaultValue();
805            if ( null != defaultValue ) {
806                Element owsRangeNode = XMLTools.appendElement( literalDataNode, OWSNS,
807                                                               "ows:DefaultValue" );
808                String closure = defaultValue.getClosure().value;
809                if ( null != closure ) {
810                    owsRangeNode.setAttribute( "ows:rangeClosure", closure );
811                }
812                String minimumValue = defaultValue.getMin().getValue();
813                if ( null != minimumValue ) {
814                    XMLTools.appendElement( owsRangeNode, OWSNS, "ows:MinimumValue", minimumValue );
815                }
816                String maximumValue = defaultValue.getMax().getValue();
817                if ( null != maximumValue ) {
818                    XMLTools.appendElement( owsRangeNode, OWSNS, "ows:MaximumValue", maximumValue );
819                }
820                String spacing = defaultValue.getSpacing().getValue();
821                if ( null != spacing ) {
822                    XMLTools.appendElement( owsRangeNode, OWSNS, "ows:Spacing", spacing );
823                }
824            }
825            LOG.exiting();
826        }
827    
828        /**
829         * 
830         * @param inputNode
831         * @param supportedCRSs
832         */
833        private static void appendBoundingBoxData( Element inputNode, SupportedCRSs supportedCRSs ) {
834            LOG.entering();
835            URI defaultCrs = supportedCRSs.getDefaultCRS();
836            Element defaultCRSs = XMLTools.appendElement( inputNode, WPSNS, "wps:BoundingBoxData", null );
837            defaultCRSs.setAttribute( "defaultCRS", defaultCrs.toString() );
838    
839            List<URI> crsList = supportedCRSs.getCRS();
840            int crsListSize = crsList.size();
841            for ( int i = 0; i < crsListSize; i++ ) {
842                URI uri = crsList.get( i );
843                XMLTools.appendElement( defaultCRSs, WPSNS, "wps:CRS", uri.toString() );
844    
845            }
846            LOG.exiting();
847        }
848    
849        /**
850         * 
851         * @param executeResponse
852         * @return
853         */
854        public static ExecuteResponseDocument export( ExecuteResponse executeResponse ) {
855            LOG.entering();
856            ExecuteResponseDocument executeResponseDocument = new ExecuteResponseDocument();
857    
858            try {
859                // Prepare empty ExecuteResponseDocument
860                executeResponseDocument.createEmptyDocument();
861    
862                // Get root of execute
863                Element root = executeResponseDocument.getRootElement();
864    
865                // Append optional statusLocation attribute
866                String statusLocation = executeResponse.getStatusLocation();
867                if ( null != statusLocation ) {
868                    root.setAttribute( "statusLocation", statusLocation );
869                }
870    
871                // Append mandatory <ows:Identifier> node
872                Code identifier = executeResponse.getIdentifier();
873                if ( null != identifier ) {
874                    appendIdentifier( root, identifier );
875                } else {
876                    LOG.logError( "identifier is null." );
877                }
878    
879                // Append mandatory <Status> node
880                appendStatus( root, executeResponse.getStatus() );
881    
882                // Append optional <DataInputs> node
883                ExecuteDataInputs executeDataInputs = executeResponse.getDataInputs();
884                if ( null != executeDataInputs ) {
885                    appendExecuteDataInputs( root, executeResponse.getDataInputs() );
886                }
887    
888                // Append optional <OutputDefinitions> node
889                OutputDefinitions outputDefinitions = executeResponse.getOutputDefinitions();
890                if ( null != outputDefinitions ) {
891                    appendOutputDefinitions( root, outputDefinitions );
892                }
893    
894                // Append optional <ProcessOutputs> node
895                ExecuteResponse.ProcessOutputs processOutputs = executeResponse.getProcessOutputs();
896                if ( null != processOutputs ) {
897                    appendExecuteProcessOutputs( root, processOutputs );
898                }
899    
900            } catch ( IOException e ) {
901                LOG.logError( e.getMessage(), e );
902            } catch ( SAXException e ) {
903                LOG.logError( e.getMessage(), e );
904            }
905            LOG.exiting();
906            return executeResponseDocument;
907        }
908    
909        /**
910         * 
911         * @param root
912         * @param status
913         */
914        private static void appendStatus( Element root, Status status ) {
915    
916            LOG.entering();
917    
918            Element statusNode = XMLTools.appendElement( root, WPSNS, "Status" );
919    
920            String processSucceeded = status.getProcessSucceeded();
921    
922            ProcessFailed processFailed = status.getProcessFailed();
923    
924            String processAccepted = status.getProcessAccepted();
925    
926            ProcessStarted processStarted = status.getProcessStarted();
927    
928            if ( null != processSucceeded ) {
929                if ( "".equals( processSucceeded ) ) {
930                    XMLTools.appendElement( statusNode, WPSNS, "ProcessSucceeded" );
931                } else {
932                    XMLTools.appendElement( statusNode, WPSNS, "ProcessSucceeded", processSucceeded );
933                }
934            }
935    
936            else if ( null != processFailed ) {
937    
938                Element processfailedNode = XMLTools.appendElement( statusNode, WPSNS, "ProcessFailed" );
939    
940                ExceptionReport exceptionReport = processFailed.getExceptionReport();
941                if ( null != exceptionReport ) {
942                    Element execeptionReportNode = XMLTools.appendElement( processfailedNode, OWSNS,
943                                                                           "ows:ExceptionReport" );
944                    String version = exceptionReport.getVersion();
945                    if ( null != version && !"".equals( version ) ) {
946                        execeptionReportNode.setAttribute( "version", version );
947                    }
948                    OGCWebServiceException[] ogcWebserviceExceptions = exceptionReport.getExceptions();
949                    int size = ogcWebserviceExceptions.length;
950                    if ( 0 < size ) {
951                        for ( int i = 0; i < size; i++ ) {
952                            appendException( execeptionReportNode, ogcWebserviceExceptions[i] );
953                        }
954                    }
955                }
956            }
957    
958            else if ( null != processAccepted ) {
959    
960                if ( "".equals( processAccepted ) ) {
961                    XMLTools.appendElement( statusNode, WPSNS, "ProcessAccepted" );
962                } else {
963                    XMLTools.appendElement( statusNode, WPSNS, "ProcessAccepted", processAccepted );
964                }
965            }
966    
967            else if ( null != processStarted ) {
968    
969                Element processStartedNode = null;
970                String processStartedMessage = processStarted.getValue();
971                if ( "".equals( processStartedMessage ) ) {
972                    processStartedNode = XMLTools.appendElement( statusNode, WPSNS, "ProcessStarted" );
973                } else {
974                    processStartedNode = XMLTools.appendElement( statusNode, WPSNS, "ProcessStarted",
975                                                                 processStartedMessage );
976                }
977                int percentCompleted = processStarted.getPercentCompleted();
978                if ( 0 >= percentCompleted && percentCompleted <= 100 ) {
979                    processStartedNode.setAttribute( "PercentCompleted",
980                                                     String.valueOf( percentCompleted ) );
981                }
982            }
983            LOG.exiting();
984        }
985    
986        /**
987         * appends a xml representation of an <tt>OGCWebServiceException</tt> to
988         * the passed <tt>Element</tt> Overriding method of superclass because the
989         * nodes appended from that method do not conform with current ows
990         * specification
991         * 
992         * @param node
993         * @param ex
994         */
995        protected static void appendException( Element node, OGCWebServiceException ex ) {
996    
997            LOG.entering();
998    
999            Element exceptionNode = XMLTools.appendElement( node, OWSNS, "ows:Exception" );
1000    
1001            if ( null != ex.getCode() ) {
1002                exceptionNode.setAttribute( "exceptionCode", ex.getCode().value );
1003            }
1004            String locator = ex.getLocator();
1005            try {
1006                if ( null != locator ) {
1007                    locator = URLEncoder.encode( locator, CharsetUtils.getSystemCharset() );
1008                } else {
1009                    locator = "-";
1010                }
1011            } catch ( UnsupportedEncodingException e ) {
1012            }
1013            exceptionNode.setAttribute( "locator", locator );
1014            LOG.exiting();
1015        }
1016    
1017        /**
1018         * 
1019         * @param root
1020         * @param executeDataInputs
1021         */
1022        private static void appendExecuteDataInputs( Element root, ExecuteDataInputs executeDataInputs ) {
1023    
1024            LOG.entering();
1025    
1026            Map<String, IOValue> inputs = executeDataInputs.getInputs();
1027    
1028            if ( null != inputs ) {
1029    
1030                int size = inputs.size();
1031    
1032                if ( 0 < size ) {
1033    
1034                    Iterator it = inputs.keySet().iterator();
1035    
1036                    Element dataInputsNode = XMLTools.appendElement( root, WPSNS, "DataInputs" );
1037    
1038                    while ( it.hasNext() ) {
1039    
1040                        IOValue ioValue = inputs.get( it.next() );
1041    
1042                        appendInput( dataInputsNode, ioValue );
1043                    }
1044                }
1045            }
1046            LOG.exiting();
1047        }
1048    
1049        /**
1050         * 
1051         * @param dataInputsNode
1052         * @param ioValue
1053         */
1054        private static void appendInput( Element dataInputsNode, IOValue ioValue ) {
1055    
1056            LOG.entering();
1057    
1058            Element inputNode = XMLTools.appendElement( dataInputsNode, WPSNS, "Input" );
1059    
1060            Code identifier = ioValue.getIdentifier();
1061            if ( null != identifier ) {
1062                appendIdentifier( inputNode, identifier );
1063            } else {
1064                LOG.logError( "identifier is null." );
1065            }
1066    
1067            String title = ioValue.getTitle();
1068            if ( null != title ) {
1069                appendTitle( inputNode, title );
1070            } else {
1071                LOG.logError( "title is null." );
1072            }
1073    
1074            String _abstract = ioValue.getAbstract();
1075            if ( null != _abstract ) {
1076                appendAbstract( inputNode, _abstract );
1077            }
1078    
1079            ComplexValue complexValue = ioValue.getComplexValue();
1080            ComplexValueReference complexValueReference = ioValue.getComplexValueReference();
1081            TypedLiteral literalValue = ioValue.getLiteralValue();
1082            Envelope boundingBoxValue = ioValue.getBoundingBoxValue();
1083    
1084            if ( null != complexValue ) {
1085                appendComplexValue( inputNode, complexValue );
1086            } else if ( null != complexValueReference ) {
1087                appendComplexValueReference( inputNode, complexValueReference );
1088            } else if ( null != literalValue ) {
1089                appendLiteralValue( inputNode, literalValue );
1090            } else if ( null != boundingBoxValue ) {
1091                appendBoundingBoxValue( inputNode, boundingBoxValue );
1092            } else {
1093                LOG.logError( "a required input element is missing." );
1094            }
1095            LOG.exiting();
1096        }
1097    
1098        /**
1099         * 
1100         * @param e
1101         * @param complexValue
1102         */
1103        private static void appendComplexValue( Element e, ComplexValue complexValue ) {
1104            LOG.entering();
1105            Element complexValueNode = XMLTools.appendElement( e, WPSNS, "ComplexValue" );
1106    
1107            String format = complexValue.getFormat();
1108            if ( null != format && !"".equals( format ) ) {
1109                complexValueNode.setAttribute( "format", format );
1110            }
1111    
1112            URI encoding = complexValue.getEncoding();
1113            if ( null != encoding ) {
1114                complexValueNode.setAttribute( "encoding", encoding.toString() );
1115            }
1116    
1117            URL schema = complexValue.getSchema();
1118            if ( null != schema ) {
1119                complexValueNode.setAttribute( "schema", schema.toString() );
1120            }
1121    
1122            Object content = complexValue.getContent();
1123    
1124            if ( content instanceof FeatureCollection ) {
1125    
1126                // TODO weird hack! are there better ways to append a
1127                // featurecollection to an element?
1128                FeatureCollection fc = (FeatureCollection) content;
1129                ByteArrayOutputStream bos = new ByteArrayOutputStream();
1130    
1131                try {
1132                    new GMLFeatureAdapter().export( fc, bos );
1133                } catch ( IOException e1 ) {
1134                    LOG.logError( "error exporting featurecollection." );
1135                } catch ( FeatureException e1 ) {
1136                    LOG.logError( "error exporting featurecollection." );
1137                }
1138    
1139                String gmlString = null;
1140                try {
1141                    gmlString = bos.toString( "UTF-8" );
1142                } catch ( UnsupportedEncodingException e1 ) {
1143                }
1144    
1145                XMLFragment xmlFragment = null;
1146                try {
1147                    xmlFragment = new XMLFragment( new StringReader( gmlString ), "http://fluggs-che" );
1148                } catch ( SAXException e1 ) {
1149                    LOG.logError( "error converting featurecollection to xmlfragment." );
1150                } catch ( IOException e1 ) {
1151                    LOG.logError( "error converting featurecollection to xmlfragment." );
1152                }
1153    
1154                Node fcElement = xmlFragment.getRootElement();
1155    
1156                Document owner = complexValueNode.getOwnerDocument();
1157    
1158                complexValueNode.appendChild( owner.importNode( fcElement, true ) );
1159    
1160            } else {
1161                // TODO implement output methods for complex value types other than
1162                // featurecollection
1163            }
1164    
1165            LOG.exiting();
1166        }
1167    
1168        /**
1169         * 
1170         * @param inputNode
1171         * @param complexValueReference
1172         */
1173        private static void appendComplexValueReference( Element inputNode,
1174                                                        ComplexValueReference complexValueReference ) {
1175            LOG.entering();
1176    
1177            Element complexValueReferenceNode = XMLTools.appendElement( inputNode, WPSNS,
1178                                                                        "ComplexValueReference" );
1179    
1180            String format = complexValueReference.getFormat();
1181            if ( null != format && !"".equals( format ) ) {
1182                complexValueReferenceNode.setAttribute( "format", format );
1183            }
1184    
1185            URI encoding = complexValueReference.getEncoding();
1186            if ( null != encoding ) {
1187                complexValueReferenceNode.setAttribute( "encoding", encoding.toString() );
1188            }
1189    
1190            URL schema = complexValueReference.getSchema();
1191            if ( null != schema ) {
1192                complexValueReferenceNode.setAttribute( "schema", schema.toString() );
1193            }
1194    
1195            URL reference = complexValueReference.getReference();
1196            if ( null != reference ) {
1197                complexValueReferenceNode.setAttributeNS( OWSNS.toString(), "ows:reference",
1198                                                          reference.toString() );
1199            }
1200    
1201            LOG.exiting();
1202        }
1203    
1204        /**
1205         * 
1206         * @param inputNode
1207         * @param literalValue
1208         */
1209        private static void appendLiteralValue( Element inputNode, TypedLiteral literalValue ) {
1210    
1211            LOG.entering();
1212    
1213            Element literalValueNode = XMLTools.appendElement( inputNode, WPSNS, "LiteralValue" );
1214    
1215            URI dataType = literalValue.getType();
1216            if ( null != dataType ) {
1217                literalValueNode.setAttribute( "dataType", dataType.toString() );
1218            }
1219    
1220            URI uom = literalValue.getUom();
1221            if ( null != uom ) {
1222                literalValueNode.setAttribute( "uom", uom.toString() );
1223            }
1224    
1225            String value = literalValue.getValue();
1226            if ( null != value && !"".equals( value ) ) {
1227                literalValueNode.setTextContent( value );
1228            }
1229    
1230            LOG.exiting();
1231        }
1232    
1233        /**
1234         * 
1235         * @param inputNode
1236         * @param boundingBoxValue
1237         */
1238        private static void appendBoundingBoxValue( Element inputNode, Envelope boundingBoxValue ) {
1239    
1240            LOG.entering();
1241    
1242            Element boundingBoxValueNode = XMLTools.appendElement( inputNode, WPSNS, "BoundingBoxValue" );
1243    
1244            String crs = boundingBoxValue.getCoordinateSystem().getName();
1245            if ( null != crs ) {
1246                boundingBoxValueNode.setAttribute( "crs", crs );
1247            }
1248    
1249            int dimensions = boundingBoxValue.getCoordinateSystem().getDimension();
1250            if ( 0 != dimensions ) {
1251                boundingBoxValueNode.setAttribute( "dimensions", String.valueOf( dimensions ) );
1252            }
1253    
1254            Position positionMin = boundingBoxValue.getMin();
1255            if ( null != positionMin ) {
1256                XMLTools.appendElement( boundingBoxValueNode, OWSNS, "ows:LowerCorner",
1257                                        String.valueOf( positionMin.getX() ) + " "
1258                                                                + String.valueOf( positionMin.getY() ) );
1259            }
1260    
1261            Position positionMax = boundingBoxValue.getMax();
1262            if ( null != positionMax ) {
1263                XMLTools.appendElement( boundingBoxValueNode, OWSNS, "ows:UpperCorner",
1264                                        String.valueOf( positionMax.getX() ) + " "
1265                                                                + String.valueOf( positionMax.getY() ) );
1266            }
1267            LOG.exiting();
1268        }
1269    
1270        /**
1271         * 
1272         * @param root
1273         * @param outputDefintions
1274         */
1275        private static void appendOutputDefinitions( Element root, OutputDefinitions outputDefintions ) {
1276    
1277            LOG.entering();
1278    
1279            Element outputDefinitionsNode = XMLTools.appendElement( root, WPSNS, "OutputDefinitions" );
1280    
1281            List<OutputDefinition> outputDefinitionsList = outputDefintions.getOutputDefinitions();
1282    
1283            if ( null != outputDefinitionsList ) {
1284    
1285                int size = outputDefinitionsList.size();
1286    
1287                if ( 0 < size ) {
1288                    for ( int i = 0; i < outputDefinitionsList.size(); i++ ) {
1289    
1290                        appendOutputDefinition( outputDefinitionsNode, outputDefinitionsList.get( i ) );
1291    
1292                    }
1293                }
1294            }
1295            LOG.exiting();
1296        }
1297    
1298        /**
1299         * 
1300         * @param outputDefinitionsNode
1301         * @param outputDefinition
1302         */
1303        private static void appendOutputDefinition( Element outputDefinitionsNode,
1304                                                   OutputDefinition outputDefinition ) {
1305    
1306            LOG.entering();
1307    
1308            Element outputNode = XMLTools.appendElement( outputDefinitionsNode, WPSNS, "Output" );
1309    
1310            String format = outputDefinition.getFormat();
1311            if ( null != format && !"".equals( format ) ) {
1312                outputNode.setAttribute( "format", format );
1313            }
1314    
1315            URI encoding = outputDefinition.getEncoding();
1316            if ( null != encoding ) {
1317                outputNode.setAttribute( "encoding", encoding.toString() );
1318            }
1319    
1320            URL schema = outputDefinition.getSchema();
1321            if ( null != schema ) {
1322                outputNode.setAttribute( "schema", schema.toString() );
1323            }
1324    
1325            URI uom = outputDefinition.getUom();
1326            if ( null != uom ) {
1327                outputNode.setAttribute( "uom", uom.toString() );
1328            }
1329    
1330            Code identifier = outputDefinition.getIdentifier();
1331            if ( null != identifier ) {
1332                appendIdentifier( outputNode, identifier );
1333            } else {
1334                LOG.logError( "identifier is null." );
1335            }
1336    
1337            String title = outputDefinition.getTitle();
1338            if ( null != title ) {
1339                appendTitle( outputNode, title );
1340            } else {
1341                LOG.logError( "title is null." );
1342            }
1343    
1344            String _abstract = outputDefinition.getAbstract();
1345            if ( null != _abstract ) {
1346                appendAbstract( outputNode, _abstract );
1347            }
1348            LOG.exiting();
1349        }
1350    
1351        /**
1352         * 
1353         * @param root
1354         * @param processOutputs
1355         */
1356        private static void appendExecuteProcessOutputs( Element root,
1357                                                        ExecuteResponse.ProcessOutputs processOutputs ) {
1358    
1359            LOG.entering();
1360    
1361            Element processOutputsNode = XMLTools.appendElement( root, WPSNS, "ProcessOutputs" );
1362    
1363            List<IOValue> processOutputsList = processOutputs.getOutputs();
1364            if ( null != processOutputsList ) {
1365    
1366                int size = processOutputsList.size();
1367                if ( 0 < size ) {
1368    
1369                    for ( int i = 0; i < size; i++ ) {
1370                        appendExecuteProcessOutput( processOutputsNode, processOutputsList.get( i ) );
1371                    }
1372                }
1373            }
1374            LOG.exiting();
1375        }
1376    
1377        /**
1378         * 
1379         * @param root
1380         * @param processOutputs
1381         */
1382        private static void appendExecuteProcessOutput( Element processOutputsNode,
1383                                                       IOValue processOutput ) {
1384    
1385            LOG.entering();
1386    
1387            Element outputNode = XMLTools.appendElement( processOutputsNode, WPSNS, "Output" );
1388    
1389            Code identifier = processOutput.getIdentifier();
1390            if ( null != identifier ) {
1391                appendIdentifier( outputNode, identifier );
1392            } else {
1393                LOG.logError( "identifier is null." );
1394            }
1395    
1396            String title = processOutput.getTitle();
1397            if ( null != title ) {
1398                appendTitle( outputNode, title );
1399            } else {
1400                LOG.logError( "title is null." );
1401            }
1402    
1403            String _abstract = processOutput.getAbstract();
1404            if ( null != _abstract ) {
1405                appendAbstract( outputNode, _abstract );
1406            }
1407    
1408            ComplexValue complexValue = processOutput.getComplexValue();
1409            ComplexValueReference complexValueReference = processOutput.getComplexValueReference();
1410            TypedLiteral literalValue = processOutput.getLiteralValue();
1411            Envelope boundingBoxValue = processOutput.getBoundingBoxValue();
1412    
1413            if ( null != complexValue ) {
1414                appendComplexValue( outputNode, complexValue );
1415            } else if ( null != complexValueReference ) {
1416                appendComplexValueReference( outputNode, complexValueReference );
1417            } else if ( null != literalValue ) {
1418                appendLiteralValue( outputNode, literalValue );
1419            } else if ( null != boundingBoxValue ) {
1420                appendBoundingBoxValue( outputNode, boundingBoxValue );
1421            } else {
1422                LOG.logError( "a required output element is missing." );
1423            }
1424            LOG.exiting();
1425        }
1426    
1427    }
1428    /* ********************************************************************
1429    Changes to this class. What the people have been up to:
1430    $Log$
1431    Revision 1.11  2007/01/31 15:42:57  taddei
1432    removed double assignment ( crs = crs = b;)
1433    
1434    Revision 1.10  2006/10/17 20:31:20  poth
1435    *** empty log message ***
1436    
1437    Revision 1.9  2006/08/24 06:42:16  poth
1438    File header corrected
1439    
1440    Revision 1.8  2006/05/25 14:47:58  poth
1441    LiteralValue substituted by TypedLiteral
1442    
1443    
1444    ********************************************************************** */