001    // $HeadURL:
002    // /cvsroot/deegree/src/org/deegree/ogcwebservices/OGCRequestFactory.java,v 1.12
003    // 2004/08/10 17:17:02 tf Exp $
004    /*----------------------------------------------------------------------------
005     This file is part of deegree, http://deegree.org/
006     Copyright (C) 2001-2009 by:
007     Department of Geography, University of Bonn
008     and
009     lat/lon GmbH
010    
011     This library is free software; you can redistribute it and/or modify it under
012     the terms of the GNU Lesser General Public License as published by the Free
013     Software Foundation; either version 2.1 of the License, or (at your option)
014     any later version.
015     This library is distributed in the hope that it will be useful, but WITHOUT
016     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
017     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
018     details.
019     You should have received a copy of the GNU Lesser General Public License
020     along with this library; if not, write to the Free Software Foundation, Inc.,
021     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022    
023     Contact information:
024    
025     lat/lon GmbH
026     Aennchenstr. 19, 53177 Bonn
027     Germany
028     http://lat-lon.de/
029    
030     Department of Geography, University of Bonn
031     Prof. Dr. Klaus Greve
032     Postfach 1147, 53001 Bonn
033     Germany
034     http://www.geographie.uni-bonn.de/deegree/
035    
036     e-mail: info@deegree.org
037     ----------------------------------------------------------------------------*/
038    package org.deegree.ogcwebservices;
039    
040    import static org.deegree.framework.util.CharsetUtils.getSystemCharset;
041    import static org.deegree.i18n.Messages.get;
042    import static org.deegree.ogcbase.ExceptionCode.INVALIDPARAMETERVALUE;
043    import static org.deegree.ogcbase.ExceptionCode.MISSINGPARAMETERVALUE;
044    import static org.deegree.ogcbase.ExceptionCode.OPERATIONNOTSUPPORTED;
045    
046    import java.io.BufferedReader;
047    import java.io.IOException;
048    import java.io.InputStreamReader;
049    import java.io.Reader;
050    import java.io.StringReader;
051    import java.io.UnsupportedEncodingException;
052    import java.net.MalformedURLException;
053    import java.net.URLDecoder;
054    import java.util.Map;
055    
056    import javax.servlet.ServletRequest;
057    import javax.servlet.http.HttpServletRequest;
058    
059    import org.deegree.framework.log.ILogger;
060    import org.deegree.framework.log.LoggerFactory;
061    import org.deegree.framework.util.CharsetUtils;
062    import org.deegree.framework.util.IDGenerator;
063    import org.deegree.framework.util.KVP2Map;
064    import org.deegree.framework.util.StringTools;
065    import org.deegree.framework.xml.XMLFragment;
066    import org.deegree.framework.xml.XMLParsingException;
067    import org.deegree.framework.xml.XMLTools;
068    import org.deegree.ogcbase.CommonNamespaces;
069    import org.deegree.ogcbase.ExceptionCode;
070    import org.deegree.ogcwebservices.csw.capabilities.CatalogueGetCapabilities;
071    import org.deegree.ogcwebservices.csw.capabilities.CatalogueOperationsMetadata;
072    import org.deegree.ogcwebservices.csw.discovery.DescribeRecord;
073    import org.deegree.ogcwebservices.csw.discovery.GetRecordById;
074    import org.deegree.ogcwebservices.csw.discovery.GetRecords;
075    import org.deegree.ogcwebservices.csw.discovery.GetRepositoryItem;
076    import org.deegree.ogcwebservices.csw.manager.Harvest;
077    import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
078    import org.deegree.ogcwebservices.sos.capabilities.SOSGetCapabilities;
079    import org.deegree.ogcwebservices.sos.capabilities.SOSOperationsMetadata;
080    import org.deegree.ogcwebservices.sos.describeplatform.DescribePlatformRequest;
081    import org.deegree.ogcwebservices.sos.describesensor.DescribeSensorRequest;
082    import org.deegree.ogcwebservices.sos.getobservation.GetObservationRequest;
083    import org.deegree.ogcwebservices.wass.common.CloseSession;
084    import org.deegree.ogcwebservices.wass.common.GetSession;
085    import org.deegree.ogcwebservices.wass.was.operation.DescribeUser;
086    import org.deegree.ogcwebservices.wass.was.operation.WASGetCapabilities;
087    import org.deegree.ogcwebservices.wass.wss.operation.DoService;
088    import org.deegree.ogcwebservices.wass.wss.operation.WSSGetCapabilities;
089    import org.deegree.ogcwebservices.wcs.describecoverage.DescribeCoverage;
090    import org.deegree.ogcwebservices.wcs.getcapabilities.WCSGetCapabilities;
091    import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage;
092    import org.deegree.ogcwebservices.wcts.operation.GetResourceByID;
093    import org.deegree.ogcwebservices.wcts.operation.GetResourceByIDDocument;
094    import org.deegree.ogcwebservices.wcts.operation.IsTransformable;
095    import org.deegree.ogcwebservices.wcts.operation.IsTransformableDocument;
096    import org.deegree.ogcwebservices.wcts.operation.Transform;
097    import org.deegree.ogcwebservices.wcts.operation.TransformDocument;
098    import org.deegree.ogcwebservices.wcts.operation.WCTSGetCapabilities;
099    import org.deegree.ogcwebservices.wcts.operation.WCTSGetCapabilitiesDocument;
100    import org.deegree.ogcwebservices.wfs.operation.DescribeFeatureType;
101    import org.deegree.ogcwebservices.wfs.operation.GetFeature;
102    import org.deegree.ogcwebservices.wfs.operation.GetFeatureWithLock;
103    import org.deegree.ogcwebservices.wfs.operation.GetGmlObject;
104    import org.deegree.ogcwebservices.wfs.operation.LockFeature;
105    import org.deegree.ogcwebservices.wfs.operation.WFSGetCapabilities;
106    import org.deegree.ogcwebservices.wfs.operation.transaction.Transaction;
107    import org.deegree.ogcwebservices.wmps.operation.PrintMap;
108    import org.deegree.ogcwebservices.wmps.operation.WMPSGetCapabilities;
109    import org.deegree.ogcwebservices.wms.operation.DescribeLayer;
110    import org.deegree.ogcwebservices.wms.operation.GetFeatureInfo;
111    import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
112    import org.deegree.ogcwebservices.wms.operation.GetMap;
113    import org.deegree.ogcwebservices.wms.operation.WMSGetCapabilities;
114    import org.deegree.ogcwebservices.wps.capabilities.WPSGetCapabilities;
115    import org.deegree.ogcwebservices.wps.describeprocess.DescribeProcessRequest;
116    import org.deegree.ogcwebservices.wps.execute.ExecuteRequest;
117    import org.deegree.ogcwebservices.wpvs.operation.Get3DFeatureInfo;
118    import org.deegree.ogcwebservices.wpvs.operation.GetView;
119    import org.deegree.ogcwebservices.wpvs.operation.WPVSGetCapabilities;
120    import org.w3c.dom.Document;
121    import org.w3c.dom.Element;
122    import org.xml.sax.SAXException;
123    
124    /**
125     * Factory for generating request objects for OGC Web Services.
126     * <p>
127     * Requests may be generated from KVP or DOM representations. Also contains methods that decide whether an incoming
128     * request representation is valid for a certain service.
129     * </p>
130     * Currently supported services are:
131     * <ul>
132     * <li>CSW</li>
133     * <li>WFS</li>
134     * <li>WCS</li>
135     * <li>WMS</li>
136     * <li>WFS-G</li>
137     * <li>SOS</li>
138     * <li>WMPS</li>
139     * <li>WSS</li>
140     * <li>WAS</li>
141     * <li>WPVS</li>
142     * </ul>
143     * 
144     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
145     * @author last edited by: $Author: apoth $
146     * 
147     * @version $Revision: 19229 $, $Date: 2009-08-19 10:02:26 +0200 (Mi, 19. Aug 2009) $
148     */
149    public class OGCRequestFactory {
150    
151        private static final ILogger LOG = LoggerFactory.getLogger( OGCRequestFactory.class );
152    
153        private static final String CSW_SERVICE_NAME = "CSW";
154    
155        /**
156         * The service name of a getRepositoryItem request, only valid for the csw/ebrim. Fixed value:
157         * "urn:x-ogc:specification:cswebrim:Service:OGC-CSW:ebRIM"
158         */
159        public static final String CSW_SERVICE_NAME_EBRIM = "urn:x-ogc:specification:cswebrim:Service:OGC-CSW:ebRIM";
160    
161        private static final String WFS_SERVICE_NAME = "WFS";
162    
163        private static final String WCS_SERVICE_NAME = "WCS";
164    
165        private static final String WMS_SERVICE_NAME = "WMS";
166    
167        private static final String SOS_SERVICE_NAME = "SOS";
168    
169        private static final String WPVS_SERVICE_NAME = "WPVS";
170    
171        private static final String WMPS_SERVICE_NAME = "WMPS";
172    
173        private static final String WPS_SERVICE_NAME = "WPS";
174    
175        private static final String WSS_SERVICE_NAME = "WSS";
176    
177        private static final String WAS_SERVICE_NAME = "WAS";
178    
179        private static final String WCTS_SERVICE_NAME = "WCTS";
180    
181        /**
182         * Creates an <code>OGCWebServiceRequest</code> from the content contained within the passed request.
183         * 
184         * @param request
185         * @return the request object
186         * @throws OGCWebServiceException
187         */
188        public static OGCWebServiceRequest create( ServletRequest request )
189                                throws OGCWebServiceException {
190    
191            Map<String, String> result = KVP2Map.toMap( request );
192    
193            LOG.logDebug( "Request parameters: " + result );
194    
195            if ( result.size() != 0 ) {
196                return createFromKVP( result );
197            }
198    
199            XMLFragment fragment = null;
200            try {
201                Reader xmlReader = null;
202                if ( LOG.isDebug() ) {
203                    LOG.logDebug( "Request's content type is " + request.getContentType() );
204                    LOG.logDebug( "Request's character encoding is " + request.getCharacterEncoding() );
205                }
206    
207                if ( request.getContentType() != null ) {
208                    if ( request.getCharacterEncoding() == null ) {
209                        request.setCharacterEncoding( getSystemCharset() );
210                    }
211                    xmlReader = request.getReader();
212    
213                    // this was a nice try, but unfortunately #getReader is not the same as #getInputStream
214    
215                    // additionally, use UTF-8/"system" charset when it's not specified in the request
216                    // if ( request.getCharacterEncoding() == null ) {
217                    // xmlReader = new InputStreamReader( request.getInputStream(), getSystemCharset() );
218                    // } else {
219                    // xmlReader = new InputStreamReader( request.getInputStream(), request.getCharacterEncoding() );
220                    // }
221                } else {
222                    // DO NOT REMOVE THIS !!!!!
223                    // IT IS ABSOLUTELY NECESSARY TO ENSURE CORRECT CHARACTER ENCODING !!!
224                    xmlReader = new StringReader( getRequestContent( (HttpServletRequest) request ) );
225                }
226                if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
227                    StringBuffer sb = new StringBuffer();
228                    BufferedReader br = new BufferedReader( xmlReader );
229                    String line = null;
230                    while ( ( line = br.readLine() ) != null ) {
231                        sb.append( line );
232                    }
233                    String content = sb.toString();
234                    LOG.logDebugFile( "OGCRequestFactory_incoming", ".xml", content );
235                    xmlReader = new StringReader( content );
236                }
237                fragment = new XMLFragment( xmlReader, XMLFragment.DEFAULT_URL );
238            } catch ( SAXException se ) {
239                String message = se.getMessage();
240                if ( message != null ) {
241                    if ( message.contains( "not allowed in prolog" ) ) {
242                        throw new OGCWebServiceException( "OGCRequestFactory",
243                                                          "No key-value pairs were given and the request"
244                                                                                  + " does not contain parsable xml",
245                                                          ExceptionCode.NOAPPLICABLECODE );
246                    }
247                    throw new OGCWebServiceException( "OGCRequestFactory", "Error parsing XML request: " + message,
248                                                      ExceptionCode.NOAPPLICABLECODE );
249                }
250                throw new OGCWebServiceException( "OGCRequestFactory", "Error parsing XML request",
251                                                  ExceptionCode.NOAPPLICABLECODE );
252            } catch ( Exception e ) {
253                LOG.logError( "Error parsing XML request: " + e.getMessage(), e );
254                throw new OGCWebServiceException( "OGCRequestFactory", "Error parsing XML request: " + e.getMessage() );
255            }
256            Document doc = fragment.getRootElement().getOwnerDocument();
257    
258            return createFromXML( doc );
259        }
260    
261        /**
262         * DO NOT REMOVE THIS !!!!! IT IS ABSOLUTLY NECESSARY TO ENSURE CORRECT CHARACTER ENCODING !!!
263         * 
264         * @param request
265         * @throws IOException
266         */
267        private static String getRequestContent( HttpServletRequest request )
268                                throws IOException {
269            String method = request.getMethod();
270    
271            if ( method.equalsIgnoreCase( "POST" ) ) {
272                String charset = request.getCharacterEncoding();
273                LOG.logDebug( "posted character encoding: ", charset );
274                if ( charset == null ) {
275                    charset = "UTF-8";
276                }
277                StringBuffer req = readPost( request, charset );
278                if ( charset.equalsIgnoreCase( CharsetUtils.getSystemCharset() ) ) {
279                    return req.toString();
280                }
281                if ( charset.equalsIgnoreCase( "UTF-8" ) && !charset.equalsIgnoreCase( CharsetUtils.getSystemCharset() ) ) {
282                    String s = new String( req.toString().getBytes(), CharsetUtils.getSystemCharset() );
283                    return s;
284                }
285                if ( !charset.equalsIgnoreCase( "UTF-8" ) && !charset.equalsIgnoreCase( CharsetUtils.getSystemCharset() ) ) {
286                    String s = new String( req.toString().getBytes(), "UTF-8" );
287                    return s;
288                }
289                return req.toString();
290            }
291    
292            String req = request.getQueryString();
293            if ( req == null ) {
294                req = readPost( request, CharsetUtils.getSystemCharset() ).toString();
295            }
296            LOG.logDebug( "request string: ", req );
297    
298            return URLDecoder.decode( req, CharsetUtils.getSystemCharset() );
299    
300        }
301    
302        /**
303         * DO NOT REMOVE THIS !!!!! IT IS ABSOLUTLY NECESSARY TO ENSURE CORRECT CHARACTER ENCODING !!!
304         * 
305         * @param request
306         * @param charset
307         * @throws UnsupportedEncodingException
308         * @throws IOException
309         */
310        private static StringBuffer readPost( HttpServletRequest request, String charset )
311                                throws UnsupportedEncodingException, IOException {
312            java.io.Reader reader = new InputStreamReader( request.getInputStream(), charset );
313            BufferedReader br = new BufferedReader( reader );
314            StringBuffer req = new StringBuffer( 10000 );
315            for ( String line = null; ( line = br.readLine() ) != null; ) {
316                req.append( ( new StringBuilder( String.valueOf( line ) ) ).append( "\n" ).toString() );
317            }
318    
319            br.close();
320            return req;
321        }
322    
323        /**
324         * Creates an instance of an <code>AbstractOGCWebServiceRequest</code> from the passed DOM object. Supported OWS are
325         * 'WMS', 'WFS', 'WCS' and 'CSW'. If a request for another service is passed or a request that isn't supported by
326         * one of the listed services an exception will be thrown. <BR>
327         * Notice that not all listed services will support request processing by reading the request to be performed from a
328         * DOM object. In this case also an exception will be thrown even if the same request may can be performed if KVP is
329         * used.
330         * 
331         * @param doc
332         * @return the request object
333         * @throws OGCWebServiceException
334         */
335        public static OGCWebServiceRequest createFromXML( Document doc )
336                                throws OGCWebServiceException {
337    
338            if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
339                XMLFragment xml = new XMLFragment();
340                xml.setRootElement( doc.getDocumentElement() );
341                LOG.logDebug( "XML request (pretty printed): ", xml.getAsPrettyString() );
342            }
343    
344            String service = XMLTools.getAttrValue( doc.getDocumentElement(), null, "service", null );
345            String request = doc.getDocumentElement().getLocalName();
346            service = getTargetService( service, request, doc );
347            if ( "unknown".equals( service ) ) {
348                throw new OGCWebServiceException( "OGCRequestFactory", "Specified service '" + service
349                                                                       + "' is not a known OGC service type." );
350            }
351            OGCWebServiceRequest ogcRequest = null;
352            if ( request == null ) {
353                throw new OGCWebServiceException( "request", "Request parameter must be set!", MISSINGPARAMETERVALUE );
354            } else if ( WMS_SERVICE_NAME.equals( service ) ) {
355                ogcRequest = getWMSRequest( request, doc );
356            } else if ( WFS_SERVICE_NAME.equals( service ) ) {
357                ogcRequest = getWFSRequest( request, doc );
358            } else if ( WCS_SERVICE_NAME.equals( service ) ) {
359                ogcRequest = getWCSRequest( request, doc );
360            } else if ( CSW_SERVICE_NAME.equals( service ) ) {
361                ogcRequest = getCSWRequest( request, doc );
362            } else if ( SOS_SERVICE_NAME.equals( service ) ) {
363                ogcRequest = getSOSRequest( request, doc );
364            } else if ( WPVS_SERVICE_NAME.equals( service ) ) {
365                ogcRequest = getSOSRequest( request, doc );
366            } else if ( WMPS_SERVICE_NAME.equals( service ) ) {
367                ogcRequest = getWMPSRequest( request, doc );
368            } else if ( WPS_SERVICE_NAME.equals( service ) ) {
369                ogcRequest = getWPSRequest( request, doc );
370            } else if ( WSS_SERVICE_NAME.equals( service ) ) {
371                ogcRequest = getWSSRequest( request, doc );
372            } else if ( WAS_SERVICE_NAME.equals( service ) ) {
373                ogcRequest = getWASRequest( request, doc );
374            } else if ( WCTS_SERVICE_NAME.equals( service ) ) {
375                ogcRequest = getWCTSRequest( request, doc );
376            } else {
377                throw new OGCWebServiceException( "OGCRequestFactory", "No handler for service " + service
378                                                                       + " in OGCRequestFactory." );
379            }
380            return ogcRequest;
381        }
382    
383        /**
384         * Creates an instance of an <code>AbstractOGCWebServiceRequest</code> from the passed KVP encoded request.
385         * Supported OWS are 'WMS', 'WFS', 'WCS' and 'CSW'. If a request for another service is passed or a request that
386         * isn't supported by one of the listed services an exception will be thrown. <BR>
387         * Notice that not all listed services will support request processing by reading the request to be performed from
388         * KVPs. In this case also an exception will be thrown even if the same request may be performed if a DOM object is
389         * used.
390         * 
391         * @param map
392         * @return the request object
393         * @throws OGCWebServiceException
394         */
395        public static OGCWebServiceRequest createFromKVP( Map<String, String> map )
396                                throws OGCWebServiceException {
397    
398            LOG.logDebug( "KVP request: ", map );
399            // request parameter given?
400            String request = map.get( "REQUEST" );
401            if ( request == null ) {
402                LOG.logInfo( "parameter: ", map );
403                throw new OGCWebServiceException( "request", get( "NO_REQUEST_PARAMETER" ), MISSINGPARAMETERVALUE );
404            }
405            // service parameter given?
406            String service = map.get( "SERVICE" );
407            if ( service == null ) {
408                // a profile of a service will be treated as a service
409                service = map.get( "PROFILE" );
410                if ( service == null ) {
411                    service = getTargetService( service, request, null );
412                }
413            }
414    
415            OGCWebServiceRequest ogcRequest = null;
416            if ( !WFS_SERVICE_NAME.equals( service ) ) {
417                map.put( "SERVICE", service );
418            }
419            if ( WMS_SERVICE_NAME.equals( service ) ) {
420                ogcRequest = getWMSRequest( request, map );
421            } else if ( WFS_SERVICE_NAME.equals( service ) ) {
422                ogcRequest = getWFSRequest( request, map );
423            } else if ( WCS_SERVICE_NAME.equals( service ) ) {
424                ogcRequest = getWCSRequest( request, map );
425            } else if ( CSW_SERVICE_NAME_EBRIM.equals( service ) || CSW_SERVICE_NAME.equals( service ) ) {
426                ogcRequest = getCSWRequest( request, map );
427            } else if ( SOS_SERVICE_NAME.equals( service ) ) {
428                ogcRequest = getSOSRequest( request, map );
429            } else if ( WPVS_SERVICE_NAME.equals( service ) ) {
430                ogcRequest = getWPVSRequest( request, map );
431            } else if ( WMPS_SERVICE_NAME.equals( service ) ) {
432                ogcRequest = getWMPSRequest( request, map );
433            } else if ( WPS_SERVICE_NAME.equals( service ) ) {
434                ogcRequest = getWPSRequest( request, map );
435            } else if ( WSS_SERVICE_NAME.equals( service ) ) {
436                ogcRequest = getWSSRequest( request, map );
437            } else if ( WAS_SERVICE_NAME.equals( service ) ) {
438                ogcRequest = getWASRequest( request, map );
439            } else if ( WCTS_SERVICE_NAME.equals( service ) ) {
440                ogcRequest = getWCTSRequest( request, map );
441            } else {
442                if ( map.get( "SERVICE" ) == null || map.get( "SERVICE" ).equals( "unknown" ) ) {
443                    throw new OGCWebServiceException( "service", get( "NO_SERVICE_SPECIFIED" ), MISSINGPARAMETERVALUE );
444                }
445    
446                throw new OGCWebServiceException( "service", get( "UNKNOWN_SERVICE_SPECIFIED", map.get( "SERVICE" ) ),
447                                                  INVALIDPARAMETERVALUE );
448            }
449            return ogcRequest;
450        }
451    
452        /**
453         * Creates the corresponding WFS request object from the given parameters.
454         * 
455         * @param request
456         * @param map
457         * @return the corresponding WFS request object
458         * @throws OGCWebServiceException
459         */
460        private static OGCWebServiceRequest getWFSRequest( String request, Map<String, String> map )
461                                throws OGCWebServiceException {
462            OGCWebServiceRequest ogcRequest = null;
463            map.put( "ID", "" + IDGenerator.getInstance().generateUniqueID() );
464            if ( request.equals( "GetCapabilities" ) ) {
465                ogcRequest = WFSGetCapabilities.create( map );
466            } else if ( request.equals( "GetFeature" ) ) {
467                ogcRequest = GetFeature.create( map );
468            } else if ( request.equals( "GetFeatureWithLock" ) ) {
469                ogcRequest = GetFeatureWithLock.create( map );
470            } else if ( request.equals( "GetGmlObject" ) ) {
471                ogcRequest = GetGmlObject.create( map );
472            } else if ( request.equals( "LockFeature" ) ) {
473                ogcRequest = LockFeature.create( map );
474            } else if ( request.equals( "DescribeFeatureType" ) ) {
475                ogcRequest = DescribeFeatureType.create( map );
476            } else if ( request.equals( "Transaction" ) ) {
477                ogcRequest = Transaction.create( map );
478            } else {
479                throw new InvalidParameterValueException( "Unknown WFS request type: '" + request + "'." );
480            }
481            return ogcRequest;
482        }
483    
484        /**
485         * Creates an <code>OGCWebServiceRequest</code> from the passed <code>Document</code>. The returned request will be
486         * a WFS request. The type of request is determined by also submitted request name. Known requests are:
487         * <ul>
488         * <li>GetCapabilities</li>
489         * <li>GetFeature</li>
490         * <li>GetFeatureWithLock</li>
491         * <li>DescribeFeatureType</li>
492         * <li>Transaction</li>
493         * <li>LockFeature</li>
494         * </ul>
495         * <p>
496         * Any other request passed to the method causes an <code>OGCWebServiceException</code> to be thrown.
497         * </p>
498         * 
499         * @param request
500         * @param doc
501         * @return created <code>OGCWebServiceRequest</code>
502         * @throws OGCWebServiceException
503         */
504        private static OGCWebServiceRequest getWFSRequest( String request, Document doc )
505                                throws OGCWebServiceException {
506            OGCWebServiceRequest ogcRequest = null;
507            String id = "" + IDGenerator.getInstance().generateUniqueID();
508            if ( request.equals( "GetCapabilities" ) ) {
509                ogcRequest = WFSGetCapabilities.create( id, doc.getDocumentElement() );
510            } else if ( request.equals( "GetFeature" ) ) {
511                ogcRequest = GetFeature.create( id, doc.getDocumentElement() );
512            } else if ( request.equals( "GetFeatureWithLock" ) ) {
513                ogcRequest = GetFeatureWithLock.create( id, doc.getDocumentElement() );
514            } else if ( request.equals( "DescribeFeatureType" ) ) {
515                ogcRequest = DescribeFeatureType.create( id, doc.getDocumentElement() );
516            } else if ( request.equals( "Transaction" ) ) {
517                ogcRequest = Transaction.create( id, doc.getDocumentElement() );
518            } else if ( request.equals( "LockFeature" ) ) {
519                ogcRequest = LockFeature.create( id, doc.getDocumentElement() );
520            } else if ( request.equals( "GetGmlObject" ) ) {
521                ogcRequest = GetGmlObject.create( id, doc.getDocumentElement() );
522            } else {
523                throw new OGCWebServiceException( "Unknown / unimplemented WFS request type: '" + request + "'.",
524                                                  OPERATIONNOTSUPPORTED );
525            }
526            return ogcRequest;
527        }
528    
529        /**
530         * Creates an <code>OGCWebServiceRequest</code> from the passed <code>Document</code>. The returned request will be
531         * a WSS request. The type of request is determined by also submitted request name. Known requests are:
532         * <ul>
533         * <li>GetCapabilities</li>
534         * <li>GetSession</li>
535         * <li>CloseSession</li>
536         * <li>DoService</li>
537         * </ul>
538         * <p>
539         * Any other request passed to the method causes an <code>OGCWebServiceException</code> to be thrown.
540         * </p>
541         * 
542         * @param request
543         * @param doc
544         * @return created <code>OGCWebServiceRequest</code>
545         * @throws OGCWebServiceException
546         */
547        private static OGCWebServiceRequest getWSSRequest( String request, Document doc )
548                                throws OGCWebServiceException {
549            OGCWebServiceRequest ogcRequest = null;
550            String id = "" + IDGenerator.getInstance().generateUniqueID();
551            if ( ( "GetCapabilities" ).equals( request ) ) {
552                ogcRequest = WSSGetCapabilities.create( id, doc.getDocumentElement() );
553            } else if ( ( "GetSession" ).equals( request ) ) {
554                ogcRequest = GetSession.create( id, doc.getDocumentElement() );
555            } else if ( ( "CloseSession" ).equals( request ) ) {
556                ogcRequest = CloseSession.create( id, doc.getDocumentElement() );
557            } else if ( ( "DoService" ).equals( request ) ) {
558                ogcRequest = DoService.create( id, doc.getDocumentElement() );
559            } else {
560                throw new OGCWebServiceException( "Unknown / unimplemented WSS request type: '" + request + "'." );
561            }
562            return ogcRequest;
563        }
564    
565        /**
566         * Creates an <code>OGCWebServiceRequest</code> from the passed <code>key value pair</code>. The returned request
567         * will be a WSS request. The type of request is determined by also submitted request name. Known requests are:
568         * <ul>
569         * <li>GetCapabilities</li>
570         * <li>GetSession</li>
571         * <li>CloseSession</li>
572         * <li>DoService</li>
573         * </ul>
574         * <p>
575         * Any other request passed to the method causes an <code>OGCWebServiceException</code> to be thrown.
576         * </p>
577         * 
578         * @param request
579         * @param kvp
580         * @return created <code>OGCWebServiceRequest</code>
581         * @throws OGCWebServiceException
582         */
583        private static OGCWebServiceRequest getWSSRequest( String request, Map<String, String> kvp )
584                                throws OGCWebServiceException {
585            OGCWebServiceRequest ogcRequest = null;
586            String id = "" + IDGenerator.getInstance().generateUniqueID();
587            if ( ( "GetCapabilities" ).equals( request ) ) {
588                ogcRequest = WSSGetCapabilities.create( id, kvp );
589            } else if ( ( "GetSession" ).equals( request ) ) {
590                ogcRequest = GetSession.create( id, kvp );
591            } else if ( ( "CloseSession" ).equals( request ) ) {
592                ogcRequest = CloseSession.create( id, kvp );
593            } else if ( ( "DoService" ).equals( request ) ) {
594                ogcRequest = DoService.create( id, kvp );
595            } else {
596                throw new OGCWebServiceException( "Unknown / unimplemented WSS request type: '" + request + "'." );
597            }
598            return ogcRequest;
599        }
600    
601        /**
602         * Creates an <code>OGCWebServiceRequest</code> from the passed <code>Document</code>. The returned request will be
603         * a WAS request. The type of request is determined by also submitted request name. Known requests are:
604         * <ul>
605         * <li>GetCapabilities</li>
606         * <li>GetSession</li>
607         * <li>CloseSession</li>
608         * </ul>
609         * <p>
610         * Any other request passed to the method causes an <code>OGCWebServiceException</code> to be thrown.
611         * </p>
612         * 
613         * @param request
614         * @param doc
615         * @return created <code>OGCWebServiceRequest</code>
616         * @throws OGCWebServiceException
617         */
618        private static OGCWebServiceRequest getWASRequest( String request, Document doc )
619                                throws OGCWebServiceException {
620            OGCWebServiceRequest ogcRequest = null;
621            String id = "" + IDGenerator.getInstance().generateUniqueID();
622            // note: DescribeUser is only supported through KVP
623            if ( ( "GetCapabilities" ).equals( request ) ) {
624                ogcRequest = WASGetCapabilities.create( id, doc.getDocumentElement() );
625            } else if ( ( "GetSession" ).equals( request ) ) {
626                ogcRequest = GetSession.create( id, doc.getDocumentElement() );
627            } else if ( ( "CloseSession" ).equals( request ) ) {
628                ogcRequest = CloseSession.create( id, doc.getDocumentElement() );
629            } else {
630                throw new OGCWebServiceException( "Unknown / unimplemented WAS request type: '" + request + "'." );
631            }
632            return ogcRequest;
633        }
634    
635        /**
636         * Creates an <code>OGCWebServiceRequest</code> from the passed <code>key value pair</code>. The returned request
637         * will be a WAS request. The type of request is determined by also submitted request name. Known requests are:
638         * <ul>
639         * <li>GetCapabilities</li>
640         * <li>GetSession</li>
641         * <li>CloseSession</li>
642         * <li>DescribeUser</li>
643         * </ul>
644         * <p>
645         * Any other request passed to the method causes an <code>OGCWebServiceException</code> to be thrown.
646         * </p>
647         * 
648         * @param request
649         * @param kvp
650         * @return created <code>OGCWebServiceRequest</code>
651         * @throws OGCWebServiceException
652         */
653        private static OGCWebServiceRequest getWASRequest( String request, Map<String, String> kvp )
654                                throws OGCWebServiceException {
655            OGCWebServiceRequest ogcRequest = null;
656            kvp.put( "SERVICE", WAS_SERVICE_NAME );
657            String id = "" + IDGenerator.getInstance().generateUniqueID();
658            if ( ( "GetCapabilities" ).equals( request ) ) {
659                ogcRequest = WASGetCapabilities.create( id, kvp );
660            } else if ( ( "GetSession" ).equals( request ) ) {
661                ogcRequest = GetSession.create( id, kvp );
662            } else if ( ( "CloseSession" ).equals( request ) ) {
663                ogcRequest = CloseSession.create( id, kvp );
664            } else if ( ( "DescribeUser" ).equals( request ) ) {
665                ogcRequest = new DescribeUser( id, kvp );
666            } else {
667                throw new OGCWebServiceException( "Unknown / unimplemented WAS request type: '" + request + "'." );
668            }
669            return ogcRequest;
670        }
671    
672        /**
673         * return the type of service the passed request targets
674         * 
675         * @param service
676         * @param request
677         * @param doc
678         * @return the type of service the passed request targets
679         */
680        public static String getTargetService( String service, String request, Document doc ) {
681    
682            if ( WMS_SERVICE_NAME.equals( service ) || isWMSRequest( request ) ) {
683                return WMS_SERVICE_NAME;
684            } else if ( WFS_SERVICE_NAME.equals( service ) || isWFSRequest( request, doc ) ) {
685                return WFS_SERVICE_NAME;
686            } else if ( WCS_SERVICE_NAME.equals( service ) || isWCSRequest( request ) ) {
687                return WCS_SERVICE_NAME;
688            } else if ( CSW_SERVICE_NAME_EBRIM.equals( service ) || CSW_SERVICE_NAME.equals( service )
689                        || isCSWRequest( request, doc ) ) {
690                return CSW_SERVICE_NAME;
691            } else if ( SOS_SERVICE_NAME.equals( service ) || isSOSRequest( request ) ) {
692                return SOS_SERVICE_NAME;
693            } else if ( WPVS_SERVICE_NAME.equals( service ) || isWPVSRequest( request ) ) {
694                return WPVS_SERVICE_NAME;
695            } else if ( WMPS_SERVICE_NAME.equals( service ) || isWMPSRequest( doc, request ) ) {
696                return WMPS_SERVICE_NAME;
697            } else if ( WPS_SERVICE_NAME.equals( service ) || isWPSRequest( request ) ) {
698                return WPS_SERVICE_NAME;
699            } else if ( WAS_SERVICE_NAME.equals( service ) || isWASRequest( request ) ) {
700                return WAS_SERVICE_NAME;
701            } else if ( WSS_SERVICE_NAME.equals( service ) || isWSSRequest( request ) ) {
702                return WSS_SERVICE_NAME;
703            } else if ( WCTS_SERVICE_NAME.equals( service ) || isWCTSRequest( doc ) ) {
704                return WCTS_SERVICE_NAME;
705            } else {
706                return "unknown";
707            }
708    
709        }
710    
711        /**
712         * @param doc
713         *            to check
714         * @return true if the namespace of the given dom-xml document equals {@link CommonNamespaces#WCTSNS}.
715         */
716        private static boolean isWCTSRequest( Document doc ) {
717            if ( doc != null ) {
718                Element root = doc.getDocumentElement();
719                if ( root != null ) {
720                    String ns = root.getNamespaceURI();
721                    return CommonNamespaces.WCTSNS.toASCIIString().equals( ns )
722                           || CommonNamespaces.DEEGREEWCTS.toASCIIString().equals( ns );
723                }
724            }
725            return false;
726        }
727    
728        /**
729         * returns true if the request is a WMPS request
730         * 
731         * @param request
732         *            name, e.g. 'GetCapabilities' name, e.g. 'PrintMap'
733         * @return true if the request is a WMPS request
734         */
735        private static boolean isWMPSRequest( Document doc, String request ) {
736            if ( doc != null ) {
737                Element root = doc.getDocumentElement();
738                if ( root != null ) {
739                    String ns = root.getNamespaceURI();
740                    if ( CommonNamespaces.WMPSNS.toASCIIString().equals( ns ) ) {
741                        return true;
742                    }
743                }
744            }
745            if ( ( "PrintMap".equals( request ) ) ) {
746                return true;
747            }
748            return false;
749        }
750    
751        /**
752         * returns true if the request is a WMS request
753         * 
754         * @param request
755         * @return true if the request is a WMS request
756         */
757        private static boolean isWMSRequest( String request ) {
758            if ( "GetMap".equals( request ) || "map".equals( request ) || "GetFeatureInfo".equals( request )
759                 || "feature_info".equals( request ) || "GetLegendGraphic".equals( request )
760                 || "GetStyles".equals( request ) || "PutStyles".equals( request ) || "DescribeLayer".equals( request ) ) {
761                return true;
762            }
763            return false;
764        }
765    
766        /**
767         * returns true if the request is a WFS request
768         * 
769         * @param request
770         * @param doc
771         * @return true if the request is a WFS request
772         */
773        private static boolean isWFSRequest( String request, Document doc ) {
774            if ( doc != null ) {
775                String s = doc.getDocumentElement().getNamespaceURI();
776                if ( CommonNamespaces.WFSNS.toString().equals( s ) ) {
777                    return true;
778                }
779            } else {
780                if ( "DescribeFeatureType".equals( request ) || "GetFeature".equals( request )
781                     || "GetFeatureWithLock".equals( request ) || "GetGmlObject".equals( request )
782                     || "Lock".equals( request ) || "Transaction".equals( request ) ) {
783                    return true;
784                }
785            }
786            return false;
787        }
788    
789        /**
790         * returns true if the request is a WCS request
791         * 
792         * @param request
793         * @return true if the request is a WCS request
794         */
795        private static boolean isWCSRequest( String request ) {
796            if ( "GetCoverage".equals( request ) || "DescribeCoverage".equals( request ) ) {
797                return true;
798            }
799            return false;
800        }
801    
802        /**
803         * returns true if the request is a CSW request
804         * 
805         * @param request
806         * @return true if the request is a CSW request
807         */
808        private static boolean isCSWRequest( String request, Document doc ) {
809            if ( doc != null ) {
810                String s = doc.getDocumentElement().getNamespaceURI();
811                if ( CommonNamespaces.CSWNS.toString().equals( s ) || CommonNamespaces.CSW202NS.toString().equals( s ) ) {
812                    return true;
813                }
814            } else {
815                if ( CatalogueOperationsMetadata.GET_RECORDS_NAME.equals( request )
816                     || CatalogueOperationsMetadata.DESCRIBE_RECORD_NAME.equals( request )
817                     || CatalogueOperationsMetadata.GET_RECORD_BY_ID_NAME.equals( request )
818                     || CatalogueOperationsMetadata.GET_DOMAIN_NAME.equals( request )
819                     || CatalogueOperationsMetadata.HARVEST_NAME.equals( request ) ) {
820                    return true;
821                }
822            }
823            return false;
824        }
825    
826        /**
827         * returns true if the request is a SOS request
828         * 
829         * @param request
830         * @return true if the request is a SOS request
831         */
832        private static boolean isSOSRequest( String request ) {
833            if ( "GetObservation".equals( request ) || "DescribeSensor".equals( request )
834                 || "DescribePlatform".equals( request ) ) {
835                return true;
836            }
837            return false;
838        }
839    
840        /**
841         * returns true if the request is a WPVS request
842         * 
843         * @param request
844         *            name, e.g. 'GetView'
845         * @return true if the request is a WPVS request
846         */
847        private static boolean isWPVSRequest( String request ) {
848            if ( "GetView".equals( request ) ) {
849                return true;
850            }
851            return false;
852        }
853    
854        /**
855         * returns true if the request is a WPS request
856         * 
857         * @param request
858         *            name, e.g. 'GetCapabilities' name, e.g. 'DescribeProcess', e.g. 'Exceute'
859         * @return true if the request is a WPS request
860         */
861        private static boolean isWPSRequest( String request ) {
862            if ( "DescribeProcess".equals( request ) || "Execute".equals( request ) ) {
863                return true;
864            }
865            return false;
866        }
867    
868        /**
869         * returns true if the request is a WAS request
870         * 
871         * @param request
872         *            name, e.g. 'GetSession' name, e.g. 'CloseSession', e.g. 'GetSAMLResponse'
873         * @return true if and only if the request contains one of the above Strings
874         */
875        private static boolean isWASRequest( String request ) {
876            if ( "GetSession".equals( request ) || "CloseSession".equals( request ) || "GetSAMLResponse".equals( request )
877                 || "DescribeUser".equals( request ) ) {
878                return true;
879            }
880            return false;
881        }
882    
883        /**
884         * returns true if the request is a WSS request
885         * 
886         * @param request
887         *            name, e.g. 'GetSession' name, e.g. 'CloseSession', e.g. 'GetSAMLResponse'
888         * @return true if and only if the request contains one of the above Strins
889         */
890        private static boolean isWSSRequest( String request ) {
891            if ( "GetSession".equals( request ) || "CloseSession".equals( request ) || "DoService".equals( request ) ) {
892                return true;
893            }
894            return false;
895        }
896    
897        /**
898         * Creates an <code>OGCWebServiceRequest</code> from the passed <code>Object</code>. the returned request will be a
899         * WCS request. The type of request is determind by the the also passed 'request' parameter. Possible requests are:
900         * <ul>
901         * <li>GetCapabilities
902         * <li>GetCoverage
903         * <li>DescribeCoverage
904         * </ul>
905         * <p>
906         * Any other request passed to the method causes an exception to be thrown.
907         * </p>
908         * 
909         * @param request
910         * @param req
911         * @return created <code>OGCWebServiceRequest</code>
912         * @throws OGCWebServiceException
913         */
914        @SuppressWarnings("unchecked")
915        private static OGCWebServiceRequest getWMSRequest( String request, Object req )
916                                throws OGCWebServiceException {
917            OGCWebServiceRequest ogcRequest = null;
918            String id = "" + IDGenerator.getInstance().generateUniqueID();
919            try {
920                Map<String, String> map = null;
921                if ( req instanceof Map ) {
922                    map = (Map<String, String>) req;
923                    map.put( "ID", id );
924                }
925                if ( request.equals( "GetCapabilities" ) || "capabilities".equals( request ) ) {
926                    if ( map != null ) {
927                        // defaulting to 1.1.1 is not possible because of spec requirements
928                        // if( ( map.get( "VERSION" ) == null ) && ( map.get( "WMTVER" ) == null ) )
929                        // {
930                        // map.put( "VERSION", "1.3.0" );
931                        // }
932                        ogcRequest = WMSGetCapabilities.create( map );
933                    }
934                } else if ( request.equals( "GetMap" ) || request.equals( "map" ) ) {
935                    if ( map != null ) {
936                        ogcRequest = GetMap.create( map );
937                    } else {
938                        ogcRequest = GetMap.create( id, (Document) req );
939                    }
940                } else if ( request.equals( "GetFeatureInfo" ) || request.equals( "feature_info" ) ) {
941                    if ( map != null ) {
942                        ogcRequest = GetFeatureInfo.create( map );
943                    }
944                } else if ( request.equals( "GetLegendGraphic" ) ) {
945                    if ( map != null ) {
946                        ogcRequest = GetLegendGraphic.create( map );
947                    }
948                } else if ( request.equals( "DescribeLayer" ) ) {
949                    if ( map != null ) {
950                        ogcRequest = DescribeLayer.create( map );
951                    }
952                } else {
953                    throw new OGCWebServiceException( "Unknown WMS request type: '" + request + "'." );
954                }
955            } catch ( MalformedURLException e ) {
956                LOG.logError( e.getLocalizedMessage(), e );
957                throw new OGCWebServiceException( e.getMessage() );
958            } catch ( XMLParsingException e ) {
959                LOG.logError( e.getLocalizedMessage(), e );
960                throw new OGCWebServiceException( e.getMessage() );
961            }
962            return ogcRequest;
963        }
964    
965        /**
966         * Creates an <code>AbstractOGCWebServiceRequest</code> from the passed <code>Object</code>. the returned request
967         * will be a WCS request. The type of request is determind by the the also passed 'request' parameter. Possible
968         * requests are:
969         * <ul>
970         * <li>GetCapabilities
971         * <li>GetCoverage
972         * <li>DescribeCoverage
973         * </ul>
974         * Any other request passed to the method causes an exception to be thrown.
975         * 
976         * @param request
977         *            a string describing the request type.
978         * @param req
979         *            the kvp-encoded request
980         * @return one of the above mentioned Requests.
981         * @throws OGCWebServiceException
982         *             if the requested operation is not one of the above mentioned, or something went wrong while creating
983         *             the request.
984         */
985        private static AbstractOGCWebServiceRequest getWCSRequest( String request, Map<String, String> req )
986                                throws OGCWebServiceException {
987            AbstractOGCWebServiceRequest ogcRequest = null;
988            String id = Long.toString( IDGenerator.getInstance().generateUniqueID() );
989            req.put( "ID", id );
990            if ( request.equals( "GetCapabilities" ) ) {
991                ogcRequest = WCSGetCapabilities.create( req );
992            } else if ( request.equals( "GetCoverage" ) ) {
993                ogcRequest = GetCoverage.create( req );
994            } else if ( request.equals( "DescribeCoverage" ) ) {
995                ogcRequest = DescribeCoverage.create( req );
996            } else {
997                throw new OGCWebServiceException( "Unknown WCS request type: '" + request + "'." );
998            }
999            return ogcRequest;
1000        }
1001    
1002        /**
1003         * Creates an <code>AbstractOGCWebServiceRequest</code> from the passed <code>Docuement</code>. the returned request
1004         * will be a WCS request. The type of request is determind by the the also passed 'request' parameter. Possible
1005         * requests are:
1006         * <ul>
1007         * <li>GetCapabilities
1008         * <li>GetCoverage
1009         * <li>DescribeCoverage
1010         * </ul>
1011         * Any other request passed to the method causes an exception to be thrown.
1012         * 
1013         * @param request
1014         *            a string describing the request type.
1015         * @param req
1016         *            the XML-encoded request
1017         * @return one of the above mentioned Requests.
1018         * @throws OGCWebServiceException
1019         *             if the requested operation is not one of the above mentioned, or something went wrong while creating
1020         *             the request.
1021         */
1022        private static AbstractOGCWebServiceRequest getWCSRequest( String request, Document req )
1023                                throws OGCWebServiceException {
1024            AbstractOGCWebServiceRequest ogcRequest = null;
1025            String id = Long.toString( IDGenerator.getInstance().generateUniqueID() );
1026            if ( request.equals( "GetCapabilities" ) ) {
1027                ogcRequest = WCSGetCapabilities.create( id, req );
1028            } else if ( request.equals( "GetCoverage" ) ) {
1029                ogcRequest = GetCoverage.create( id, req );
1030            } else if ( request.equals( "DescribeCoverage" ) ) {
1031                ogcRequest = DescribeCoverage.create( id, req );
1032            } else {
1033                throw new OGCWebServiceException( "Unknown WCS request type: '" + request + "'." );
1034            }
1035            return ogcRequest;
1036        }
1037    
1038        /**
1039         * Creates an <code>AbstractOGCWebServiceRequest</code> from the passed <code>Object</code>. The returned request
1040         * will be a <code>CSW</code> request. The type of request is determined by the the also passed 'request' parameter.
1041         * Allowed values for the request parameter are:
1042         * <ul>
1043         * <li>GetCapabilities</li>
1044         * <li>GetRecords</li>
1045         * <li>GetRecordsByID</li>
1046         * <li>DescribeRecord</li>
1047         * <li>GetDomain, will cause an exception to be thrown</li>
1048         * <li>Transaction, will cause an exception to be thrown</li>
1049         * <li>Harvest</li>
1050         * </ul>
1051         * 
1052         * Any other request passed to the method causes an exception to be thrown.
1053         * 
1054         * @param request
1055         *            a string describing the request type.
1056         * @param req
1057         *            the KVP-encoded request
1058         * @return one of the above mentioned Requests.
1059         * @throws OGCWebServiceException
1060         *             if the requested operation is not one of the above mentioned, not supported or something went wrong
1061         *             while creating the request.
1062         */
1063        private static AbstractOGCWebServiceRequest getCSWRequest( String request, Map<String, String> req )
1064                                throws OGCWebServiceException {
1065            AbstractOGCWebServiceRequest ogcRequest = null;
1066            String id = Long.toString( IDGenerator.getInstance().generateUniqueID() );
1067            LOG.logDebug( StringTools.concat( 200, "Creating CSW request '", request, "' with ID=", id, "/type:",
1068                                              req.getClass().getName() ) );
1069    
1070            if ( OperationsMetadata.GET_CAPABILITIES_NAME.equals( request ) ) {
1071                req.put( "ID", id );
1072                ogcRequest = CatalogueGetCapabilities.create( req );
1073            } else if ( CatalogueOperationsMetadata.GET_RECORDS_NAME.equals( request ) ) {
1074                req.put( "ID", id );
1075                ogcRequest = GetRecords.create( req );
1076            } else if ( CatalogueOperationsMetadata.GET_RECORD_BY_ID_NAME.equals( request ) ) {
1077                // req.put( "ID", id );
1078                ogcRequest = GetRecordById.create( id, req );
1079            } else if ( CatalogueOperationsMetadata.GET_REPOSITORY_ITEM.equals( request ) ) {
1080                req.put( "REQUESTID", id );
1081                ogcRequest = GetRepositoryItem.create( req );
1082            } else if ( CatalogueOperationsMetadata.DESCRIBE_RECORD_NAME.equals( request ) ) {
1083                req.put( "ID", id );
1084                ogcRequest = DescribeRecord.create( req );
1085            } else if ( CatalogueOperationsMetadata.GET_DOMAIN_NAME.equals( request ) ) {
1086                // TODO
1087                throw new OGCWebServiceException( CatalogueOperationsMetadata.TRANSACTION_NAME + " is not supported." );
1088            } else if ( CatalogueOperationsMetadata.TRANSACTION_NAME.equals( request ) ) {
1089                throw new OGCWebServiceException( CatalogueOperationsMetadata.TRANSACTION_NAME
1090                                                  + " through HTTP Get is not supported." );
1091            } else if ( CatalogueOperationsMetadata.HARVEST_NAME.equals( request ) ) {
1092                req.put( "ID", id );
1093                ogcRequest = Harvest.create( req );
1094            } else {
1095                throw new OGCWebServiceException( "Unknown CSW request type: '" + request + "'." );
1096            }
1097            LOG.logDebug( "CSW request created: " + ogcRequest );
1098            return ogcRequest;
1099        }
1100    
1101        /**
1102         * Creates an <code>AbstractOGCWebServiceRequest</code> from the passed <code>Object</code>. The returned request
1103         * will be a <code>CSW</code> request. The type of request is determined by the the also passed 'request' parameter.
1104         * Allowed values for the request parameter are:
1105         * <ul>
1106         * <li>GetCapabilities</li>
1107         * <li>GetRecords</li>
1108         * <li>GetRecordsByID</li>
1109         * <li>DescribeRecord</li>
1110         * <li>GetDomain, will cause an exception to be thrown</li>
1111         * <li>Transaction</li>
1112         * <li>Harvest, will cause an exception to be thrown</li>
1113         * </ul>
1114         * 
1115         * Any other request passed to the method causes an exception to be thrown.
1116         * 
1117         * @param request
1118         *            a string describing the request type.
1119         * @param req
1120         *            the XML-encoded request
1121         * @return one of the above mentioned Requests.
1122         * @throws OGCWebServiceException
1123         *             if the requested operation is not one of the above mentioned, or something went wrong while creating
1124         *             the request.
1125         */
1126        private static AbstractOGCWebServiceRequest getCSWRequest( String request, Document req )
1127                                throws OGCWebServiceException {
1128            AbstractOGCWebServiceRequest ogcRequest = null;
1129            String id = Long.toString( IDGenerator.getInstance().generateUniqueID() );
1130            LOG.logDebug( StringTools.concat( 200, "Creating CSW request '", request, "' with ID=", id, "/type:",
1131                                              req.getClass().getName() ) );
1132            Element docElem = req.getDocumentElement();
1133            if ( OperationsMetadata.GET_CAPABILITIES_NAME.equals( request ) ) {
1134                ogcRequest = CatalogueGetCapabilities.create( id, docElem );
1135            } else if ( CatalogueOperationsMetadata.GET_RECORDS_NAME.equals( request ) ) {
1136                ogcRequest = GetRecords.create( id, docElem );
1137            } else if ( CatalogueOperationsMetadata.GET_RECORD_BY_ID_NAME.equals( request ) ) {
1138                ogcRequest = GetRecordById.create( id, docElem );
1139            } else if ( CatalogueOperationsMetadata.GET_REPOSITORY_ITEM.equals( request ) ) {
1140                throw new OGCWebServiceException( CatalogueOperationsMetadata.GET_REPOSITORY_ITEM + " is not supported." );
1141            } else if ( CatalogueOperationsMetadata.DESCRIBE_RECORD_NAME.equals( request ) ) {
1142                ogcRequest = DescribeRecord.create( id, docElem );
1143            } else if ( CatalogueOperationsMetadata.GET_DOMAIN_NAME.equals( request ) ) {
1144                // TODO
1145                throw new OGCWebServiceException( CatalogueOperationsMetadata.TRANSACTION_NAME + " is not supported." );
1146            } else if ( CatalogueOperationsMetadata.TRANSACTION_NAME.equals( request ) ) {
1147                ogcRequest = org.deegree.ogcwebservices.csw.manager.Transaction.create( id, docElem );
1148            } else if ( CatalogueOperationsMetadata.HARVEST_NAME.equals( request ) ) {
1149                throw new OGCWebServiceException( CatalogueOperationsMetadata.HARVEST_NAME
1150                                                  + " through HTTP post is not supported." );
1151            } else {
1152                throw new OGCWebServiceException( "Unknown CSW request type: '" + request + "'." );
1153            }
1154            LOG.logDebug( "CSW request created: " + ogcRequest );
1155            return ogcRequest;
1156        }
1157    
1158        /**
1159         * 
1160         * @param request
1161         * @param req
1162         * @return created <code>OGCWebServiceRequest</code>
1163         * @throws OGCWebServiceException
1164         */
1165        @SuppressWarnings("unchecked")
1166        private static AbstractOGCWebServiceRequest getSOSRequest( String request, Object req )
1167                                throws OGCWebServiceException {
1168    
1169            AbstractOGCWebServiceRequest ogcRequest = null;
1170    
1171            String id = "" + IDGenerator.getInstance().generateUniqueID();
1172    
1173            LOG.logDebug( "Creating SOS request '" + request + "' with ID=" + id + "/type:" + req.getClass().getName() );
1174    
1175            if ( req instanceof Map ) {
1176                ( (Map) req ).put( "ID", id );
1177            }
1178    
1179            if ( OperationsMetadata.GET_CAPABILITIES_NAME.equals( request ) ) {
1180                if ( req instanceof Map ) {
1181                    ogcRequest = SOSGetCapabilities.create( (Map) req );
1182                } else {
1183                    ogcRequest = SOSGetCapabilities.create( id, (Document) req );
1184                }
1185    
1186            } else if ( SOSOperationsMetadata.DESCRIBE_PLATFORM_NAME.equals( request ) ) {
1187                if ( req instanceof Map ) {
1188                    ogcRequest = DescribePlatformRequest.create( (Map) req );
1189                } else {
1190                    ogcRequest = DescribePlatformRequest.create( id, (Document) req );
1191                }
1192    
1193            } else if ( SOSOperationsMetadata.DESCRIBE_SENSOR_NAME.equals( request ) ) {
1194                if ( req instanceof Map ) {
1195                    ogcRequest = DescribeSensorRequest.create( (Map) req );
1196                } else {
1197                    ogcRequest = DescribeSensorRequest.create( id, (Document) req );
1198                }
1199            } else if ( SOSOperationsMetadata.GET_OBSERVATION_NAME.equals( request ) ) {
1200                if ( req instanceof Map ) {
1201                    ogcRequest = GetObservationRequest.create( (Map) req );
1202                } else {
1203                    ogcRequest = GetObservationRequest.create( id, (Document) req );
1204                }
1205            } else {
1206                throw new OGCWebServiceException( "Unknown SCS request type: '" + request + "'." );
1207            }
1208            LOG.logDebug( "SCS request created: " + ogcRequest );
1209            return ogcRequest;
1210        }
1211    
1212        /**
1213         * Creates an <code>OGCWebServiceRequest</code> from the passed <code>XML-Document</code>. the returned request will
1214         * be a WPVS request. The type of request is determind by the the also passed 'request' parameter. Possible requests
1215         * are:
1216         * <ul>
1217         * <li>GetCapabilities
1218         * <li>GetView
1219         * </ul>
1220         * <p>
1221         * Any other request passed to the method causes an exception to be thrown.
1222         * </p>
1223         * 
1224         * @param requestName
1225         *            name of the request, one of GetCapabilities or GetView
1226         * @param request
1227         *            the request as an xml document
1228         * @return created <code>OGCWebServiceRequest</code>
1229         * @throws OGCWebServiceException
1230         */
1231        @SuppressWarnings("unused")
1232        private static OGCWebServiceRequest getWPVSRequest( String requestName, Document request )
1233                                throws OGCWebServiceException {
1234            OGCWebServiceRequest ogcRequest = null;
1235            String id = Long.toString( IDGenerator.getInstance().generateUniqueID() );
1236    
1237            if ( OperationsMetadata.GET_CAPABILITIES_NAME.equals( requestName ) ) {
1238                // ogcRequest = WPVSGetCapabilities.create(id, (Document) req);
1239            } else if ( "GetView".equals( requestName ) ) {
1240                // ogcRequest = GetView.create( req );
1241            } else {
1242                throw new OGCWebServiceException( "Unknown WPVS request type: '" + requestName + "'." );
1243            }
1244            return ogcRequest;
1245        }
1246    
1247        /**
1248         * Creates an <code>OGCWebServiceRequest</code> from the passed <code>KVP-Map</code>. the returned request will be a
1249         * WPVS request. The type of request is determind by the the also passed 'request' parameter. Possible requests are:
1250         * <ul>
1251         * <li>GetCapabilities
1252         * <li>GetView
1253         * </ul>
1254         * <p>
1255         * Any other request passed to the method causes an exception to be thrown.
1256         * </p>
1257         * 
1258         * @param requestName
1259         *            name of the request, one of GetCapabilities or GetView
1260         * @param request
1261         *            the actual parameters of the request
1262         * @return created <code>OGCWebServiceRequest</code>
1263         * @throws OGCWebServiceException
1264         */
1265        private static OGCWebServiceRequest getWPVSRequest( String requestName, Map<String, String> request )
1266                                throws OGCWebServiceException {
1267            OGCWebServiceRequest ogcRequest = null;
1268            String id = Long.toString( IDGenerator.getInstance().generateUniqueID() );
1269    
1270            if ( OperationsMetadata.GET_CAPABILITIES_NAME.equals( requestName ) ) {
1271                request.put( "ID", id );
1272                ogcRequest = WPVSGetCapabilities.create( request );
1273            } else if ( "GetView".equals( requestName ) ) {
1274                ogcRequest = GetView.create( request );
1275            } else if ( "Get3DFeatureInfo".equals( requestName ) ) {
1276                ogcRequest = Get3DFeatureInfo.create( request );
1277            } else {
1278                throw new OGCWebServiceException( "Unknown WPVS request type: '" + requestName + "'." );
1279            }
1280            return ogcRequest;
1281        }
1282    
1283        /**
1284         * Creates an <code>AbstractOGCWebServiceRequest</code> from the passed <code>Object</code>. the returned request
1285         * will be a WMPS request. The type of request is determind by the the also passed 'request' parameter. Possible
1286         * requests are:
1287         * <ul>
1288         * <li>GetCapabilities
1289         * </ul>
1290         * Any other request passed to the method causes an exception to be thrown.
1291         * 
1292         * @param request
1293         * @param doc
1294         * @param req
1295         * @return created <code>OGCWebServiceRequest</code>
1296         * @throws OGCWebServiceException
1297         * @throws OGCWebServiceException
1298         */
1299        private static OGCWebServiceRequest getWMPSRequest( String request, Document doc )
1300                                throws OGCWebServiceException {
1301            OGCWebServiceRequest ogcRequest = null;
1302    
1303            if ( request.equals( "PrintMap" ) ) {
1304                try {
1305                    ogcRequest = PrintMap.create( doc.getDocumentElement() );
1306                } catch ( Exception e ) {
1307                    throw new OGCWebServiceException( "Error creating a Print Map object for the request '" + request
1308                                                      + "'. " + e.getMessage() );
1309                }
1310            } else {
1311                throw new OGCWebServiceException( "Unknown / unimplemented WMPS request type: '" + request + "'." );
1312            }
1313            return ogcRequest;
1314        }
1315    
1316        /**
1317         * Creates an <code>AbstractOGCWebServiceRequest</code> from the passed <code>Object</code>. the returned request
1318         * will be a WMPS request. The type of request is determind by the the also passed 'request' parameter. Possible
1319         * requests are:
1320         * <ul>
1321         * <li>GetCapabilities
1322         * </ul>
1323         * Any other request passed to the method causes an exception to be thrown.
1324         * 
1325         * @param request
1326         * @param map
1327         * @param req
1328         * @return OGCWebServiceRequest
1329         * @throws InconsistentRequestException
1330         * @throws InvalidParameterValueException
1331         * @throws OGCWebServiceException
1332         */
1333        private static OGCWebServiceRequest getWMPSRequest( String request, Map<String, String> map )
1334                                throws InconsistentRequestException, InvalidParameterValueException {
1335            OGCWebServiceRequest ogcRequest = null;
1336            map.put( "ID", "" + IDGenerator.getInstance().generateUniqueID() );
1337            if ( request.equals( "GetCapabilities" ) ) {
1338                ogcRequest = WMPSGetCapabilities.create( map );
1339            } else if ( request.equals( "PrintMap" ) ) {
1340                ogcRequest = PrintMap.create( map );
1341            } else {
1342                throw new InvalidParameterValueException( "Unknown WMPS request type: '" + request + "'." );
1343            }
1344            return ogcRequest;
1345        }
1346    
1347        /**
1348         * Creates an <code>OGCWebServiceRequest</code> from the passed <code>Map</code>. The returned request will be a WPS
1349         * request. The type of request is determined by also submitted request name. Known requests are:
1350         * <ul>
1351         * <li>GetCapabilities</li>
1352         * <li>DescribeProcess</li>
1353         * <li>Execute</li>
1354         * </ul>
1355         * <p>
1356         * Any other request passed to the method causes an <code>OGCWebServiceException</code> to be thrown.
1357         * </p>
1358         * 
1359         * @param request
1360         * @param map
1361         * @return created <code>OGCWebServiceRequest</code>
1362         * @throws OGCWebServiceException
1363         */
1364        private static OGCWebServiceRequest getWPSRequest( String request, Map<String, String> map )
1365                                throws OGCWebServiceException {
1366            OGCWebServiceRequest ogcRequest = null;
1367            map.put( "ID", "" + IDGenerator.getInstance().generateUniqueID() );
1368            if ( "GetCapabilities".equals( request ) ) {
1369                ogcRequest = WPSGetCapabilities.create( map );
1370            } else if ( "DescribeProcess".equals( request ) ) {
1371                ogcRequest = DescribeProcessRequest.create( map );
1372            } else if ( "Execute".equals( request ) ) {
1373                ogcRequest = ExecuteRequest.create( map );
1374            } else {
1375                throw new InvalidParameterValueException( "Unknown WPS request type: '" + request + "'." );
1376            }
1377            return ogcRequest;
1378        }
1379    
1380        /**
1381         * Creates an <code>OGCWebServiceRequest</code> from the passed <code>Document</code>. The returned request will be
1382         * a WPS request. The type of request is determined by also submitted request name. Known requests are:
1383         * <ul>
1384         * <li>GetCapabilities</li>
1385         * <li>DescribeProcess</li>
1386         * <li>Execute</li>
1387         * </ul>
1388         * <p>
1389         * Any other request passed to the method causes an <code>OGCWebServiceException</code> to be thrown.
1390         * </p>
1391         * 
1392         * @param request
1393         * @param doc
1394         * @return created <code>OGCWebServiceRequest</code>
1395         * @throws OGCWebServiceException
1396         */
1397        private static OGCWebServiceRequest getWPSRequest( String request, Document doc )
1398                                throws OGCWebServiceException {
1399            OGCWebServiceRequest ogcRequest = null;
1400            String id = "" + IDGenerator.getInstance().generateUniqueID();
1401            if ( "GetCapabilities".equals( request ) ) {
1402                ogcRequest = WPSGetCapabilities.create( id, doc.getDocumentElement() );
1403            } else if ( "DescribeProcess".equals( request ) ) {
1404                ogcRequest = DescribeProcessRequest.create( id, doc.getDocumentElement() );
1405    
1406            } else if ( "Execute".equals( request ) ) {
1407                ogcRequest = ExecuteRequest.create( id, doc.getDocumentElement() );
1408    
1409            } else {
1410                throw new OGCWebServiceException( "Unknown WPS request type: '" + request + "'." );
1411            }
1412            return ogcRequest;
1413        }
1414    
1415        /**
1416         * @param request
1417         *            containing the local-name of the top root element.
1418         * @param doc
1419         * @return
1420         * @throws IllegalArgumentException
1421         * @throws OGCWebServiceException
1422         */
1423        private static OGCWebServiceRequest getWCTSRequest( String request, Document doc )
1424                                throws OGCWebServiceException, IllegalArgumentException {
1425            OGCWebServiceRequest result = null;
1426            String requestID = Long.toString( IDGenerator.getInstance().generateUniqueID() );
1427            if ( "GetResourceByID".equals( request ) ) {
1428                result = new GetResourceByIDDocument( requestID, doc.getDocumentElement() ).getResourceById();
1429            } else if ( "GetCapabilities".equals( request ) ) {
1430                result = new WCTSGetCapabilitiesDocument( requestID, doc.getDocumentElement() ).getGetCapabilities();
1431            } else if ( "Transform".equals( request ) ) {
1432                result = new TransformDocument( requestID, doc.getDocumentElement() ).getTransformRequest();
1433            } else if ( "IsTransformable".equals( request ) ) {
1434                result = new IsTransformableDocument( requestID, doc.getDocumentElement() ).getIsTransformable();
1435            } else if ( "GetTransformation".equals( request ) ) {
1436                throw new OGCWebServiceException( "GetTransformation requests are currently not supported by the WCTS",
1437                                                  ExceptionCode.OPERATIONNOTSUPPORTED );
1438                // result = new Document(requestID, doc.getDocumentElement() ).getIsTransformable();
1439            } else {
1440                throw new OGCWebServiceException( request + " is not known to the WCTS",
1441                                                  ExceptionCode.OPERATIONNOTSUPPORTED );
1442            }
1443            return result;
1444        }
1445    
1446        /**
1447         * @param request
1448         * @param map
1449         * @return
1450         * @throws OGCWebServiceException
1451         */
1452        private static OGCWebServiceRequest getWCTSRequest( String request, Map<String, String> map )
1453                                throws OGCWebServiceException {
1454            OGCWebServiceRequest result = null;
1455            String requestID = Long.toString( IDGenerator.getInstance().generateUniqueID() );
1456            if ( "GetResourceByID".equals( request ) ) {
1457                result = GetResourceByID.create( requestID, map );
1458            } else if ( "GetCapabilities".equals( request ) ) {
1459                result = WCTSGetCapabilities.create( requestID, map );
1460            } else if ( "Transform".equals( request ) ) {
1461                result = Transform.create( requestID, map );
1462            } else if ( "IsTransformable".equals( request ) ) {
1463                result = IsTransformable.create( requestID, map );
1464            } else if ( "GetTransformation".equals( request ) ) {
1465                throw new OGCWebServiceException( "GetTransformation requests are currently not supported by the WCTS",
1466                                                  ExceptionCode.OPERATIONNOTSUPPORTED );
1467                // result = new Document(requestID, doc.getDocumentElement() ).getIsTransformable();
1468            } else {
1469                throw new OGCWebServiceException( request + " is not known to the WCTS",
1470                                                  ExceptionCode.OPERATIONNOTSUPPORTED );
1471            }
1472            return result;
1473        }
1474    
1475    }