//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/enterprise/servlet/WFSHandler.java,v 1.49 2006/10/20 15:35:41 poth Exp $ /*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstraße 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.enterprise.servlet; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.URI; import java.net.URL; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletResponse; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.deegree.datatypes.QualifiedName; import org.deegree.enterprise.ServiceException; import org.deegree.framework.log.ILogger; import org.deegree.framework.log.LoggerFactory; import org.deegree.framework.util.CharsetUtils; import org.deegree.framework.util.FileUtils; import org.deegree.framework.xml.XMLFragment; import org.deegree.framework.xml.XSLTDocument; import org.deegree.i18n.Messages; import org.deegree.io.datastore.schema.MappedFeatureType; import org.deegree.model.feature.FeatureCollection; import org.deegree.model.feature.GMLFeatureAdapter; import org.deegree.ogcwebservices.OGCWebServiceException; import org.deegree.ogcwebservices.OGCWebServiceRequest; import org.deegree.ogcwebservices.getcapabilities.DCPType; import org.deegree.ogcwebservices.getcapabilities.HTTP; import org.deegree.ogcwebservices.getcapabilities.Operation; import org.deegree.ogcwebservices.wfs.WFService; import org.deegree.ogcwebservices.wfs.WFServiceFactory; import org.deegree.ogcwebservices.wfs.XMLFactory; import org.deegree.ogcwebservices.wfs.capabilities.FormatType; import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities; import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument; import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType; import org.deegree.ogcwebservices.wfs.capabilities.WFSOperationsMetadata; import org.deegree.ogcwebservices.wfs.configuration.WFSConfiguration; import org.deegree.ogcwebservices.wfs.operation.AbstractWFSRequest; import org.deegree.ogcwebservices.wfs.operation.DescribeFeatureType; import org.deegree.ogcwebservices.wfs.operation.FeatureResult; import org.deegree.ogcwebservices.wfs.operation.FeatureTypeDescription; import org.deegree.ogcwebservices.wfs.operation.GetFeature; import org.deegree.ogcwebservices.wfs.operation.Query; import org.deegree.ogcwebservices.wfs.operation.WFSGetCapabilities; import org.deegree.ogcwebservices.wfs.operation.transaction.Delete; import org.deegree.ogcwebservices.wfs.operation.transaction.Insert; import org.deegree.ogcwebservices.wfs.operation.transaction.Transaction; import org.deegree.ogcwebservices.wfs.operation.transaction.TransactionOperation; import org.deegree.ogcwebservices.wfs.operation.transaction.TransactionResponse; import org.deegree.ogcwebservices.wfs.operation.transaction.Update; /** * Web servlet client for WFS. * <p> * NOTE: Currently, the <code>WFSHandler</code> is responsible for the pre- and postprocessing of * virtual feature types. For virtual feature types, requests and responses are transformed using an * XSL-script. Virtual feature types can also provide their own schema document that is sent as a * response to {@link DescribeFeatureType} requests. * <p> * The heuristics that determines whether pre- or postprocessing is necessary, is not very * accurate; check the methods: * <ul> * <li><code>#determineFormat(DescribeFeatureType, WFSConfiguration)</code></li> * <li><code>#determineFormat(GetFeature, WFSConfiguration)</code></li> * <li><code>#determineFormat(Transaction, WFSConfiguration)</code></li> * </ul> * <p> * The code for the handling of virtual features should probably be moved to the {@link WFService} * class. * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </a> * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </a> * @author last edited by: $Author: poth $ * * @version $Revision: 1.49 $, $Date: 2006/10/20 15:35:41 $ */ class WFSHandler extends AbstractOWServiceHandler { private static ILogger LOG = LoggerFactory.getLogger( WFSHandler.class ); /** * Performs the given {@link OGCWebServiceRequest} on the {@link WFService} and sends the * response to the given {@link HttpServletResponse} object. * * @param request * OGCWebServiceRequest to be performed * @param httpResponse * servlet response object to write to * @throws ServiceException */ public void perform( OGCWebServiceRequest request, HttpServletResponse httpResponse ) throws ServiceException { LOG.logDebug( "Performing request: " + request.toString() ); try { WFService service = WFServiceFactory.createInstance(); if ( request instanceof WFSGetCapabilities ) { performGetCapabilities( service, (WFSGetCapabilities) request, httpResponse ); } else if ( request instanceof DescribeFeatureType ) { performDescribeFeatureType( service, (DescribeFeatureType) request, httpResponse ); } else if ( request instanceof GetFeature ) { performGetFeature( service, (GetFeature) request, httpResponse ); } else if ( request instanceof Transaction ) { performTransaction( service, (Transaction) request, httpResponse ); } else { assert false : "Unhandled WFS request type: '" + request.getClass().getName() + "'"; } } catch ( OGCWebServiceException e ) { LOG.logInfo( "Error while performing WFS request.", e ); sendException( httpResponse, e ); } catch ( Exception e ) { LOG.logError( "Fatal error while performing WFS request.", e ); sendException( httpResponse, new OGCWebServiceException( getClass().getName(), e.getMessage() ) ); } } /** * Performs a {@link WFSGetCapabilities} request and sends the response to the given * {@link HttpServletResponse} object. * * @param service * WFService instance to be used * @param request * GetCapabilities request to be performed * @param httpResponse * servlet response object to write to * @throws OGCWebServiceException */ private void performGetCapabilities( WFService service, WFSGetCapabilities request, HttpServletResponse httpResponse ) throws OGCWebServiceException { WFSCapabilities capa = (WFSCapabilities) service.doService( request ); try { httpResponse.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() ); WFSCapabilitiesDocument document = XMLFactory.export( capa, request.getSections() ); document.write( httpResponse.getOutputStream() ); } catch ( IOException e ) { LOG.logError( "Error sending GetCapabilities response to client.", e ); } } /** * Performs a {@link DescribeFeatureType} request and sends the response to the given * {@link HttpServletResponse} object. * * @param service * WFService instance to be used * @param request * DescribeFeatureType request to be performed * @param httpResponse * servlet response object to write to * @throws OGCWebServiceException */ private void performDescribeFeatureType( WFService service, DescribeFeatureType request, HttpServletResponse httpResponse ) throws OGCWebServiceException { WFSConfiguration config = (WFSConfiguration) service.getCapabilities(); FormatType format = determineFormat( request, config ); XMLFragment schemaDoc = null; if ( format.getSchemaLocation() != null ) { // read special schema for virtual format try { schemaDoc = new XMLFragment( format.getSchemaLocation().toURL() ); } catch ( Exception e ) { String msg = Messages.getMessage( "WFS_VIRTUAL_FORMAT_SCHEMA_READ_ERROR", format.getSchemaLocation(), format.getValue(), e ); LOG.logError( msg, e ); throw new OGCWebServiceException( getClass().getName(), msg ); } } else { // get schema from WFService FeatureTypeDescription ftDescription = (FeatureTypeDescription) service.doService( request ); schemaDoc = ftDescription.getFeatureTypeSchema(); } httpResponse.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() ); try { schemaDoc.write( httpResponse.getOutputStream() ); } catch ( IOException e ) { LOG.logError( "Error sending DescribeFeatureType response to client.", e ); } } /** * Performs a {@link GetFeature} request and sends the response to the given * {@link HttpServletResponse} object. * * @param service * WFService instance to be used * @param request * GetFeature request to be performed * @param httpResponse * servlet response object to write to * @throws OGCWebServiceException */ private void performGetFeature( WFService service, GetFeature request, HttpServletResponse httpResponse ) throws OGCWebServiceException { WFSConfiguration config = (WFSConfiguration) service.getCapabilities(); FormatType formatType = determineFormat( request, config ); // perform pre-processing if necessary (XSLT) if ( formatType.isVirtual() ) { request = transformGetFeature( request, formatType ); } // perform request on WFService FeatureResult result = (FeatureResult) service.doService( request ); FeatureCollection fc = (FeatureCollection) result.getResponse(); String format = formatType.getValue(); if ( GetFeature.FORMAT_FEATURECOLLECTION.equals( format ) ) { sendBinaryResponse( fc, httpResponse ); } else if ( AbstractWFSRequest.FORMAT_XML.equals( format ) || format.startsWith( "text/xml; subtype=" ) ) { if ( formatType.getOutFilter() != null ) { sendTransformedResponse( fc, httpResponse, formatType ); } else { String schemaURL = buildSchemaURL( service, request ); sendGMLResponse( fc, httpResponse, schemaURL, suppressXLinkOutput( request, service ) ); } } else { String msg = Messages.getMessage( "WFS_QUERY_UNSUPPORTED_FORMAT2", format ); throw new OGCWebServiceException( msg ); } } /** * Builds a KVP-encoded DescribeFeatureType-request that can be used to fetch the schemas * for all feature types are that queried in the given {@link GetFeature} request. * * @param service * @param request * @return KVP-encoded DescribeFeatureType-request */ private String buildSchemaURL( WFService service, GetFeature request ) { String schemaURL = null; WFSCapabilities capa = (WFSCapabilities) service.getCapabilities(); WFSOperationsMetadata opMetadata = (WFSOperationsMetadata) capa.getOperationsMetadata(); Operation describeFTOperation = opMetadata.getDescribeFeatureType(); DCPType[] dcpTypes = describeFTOperation.getDCPs(); if ( dcpTypes.length > 0 && dcpTypes[0].getProtocol() instanceof HTTP ) { HTTP http = (HTTP) dcpTypes[0].getProtocol(); if ( http.getGetOnlineResources().length > 0 ) { URL baseURL = http.getGetOnlineResources()[0]; String requestPart = buildDescribeFTRequest( request ); schemaURL = baseURL.toString() + requestPart; } } return schemaURL; } /** * Builds the parameter part for a KVP-encoded DescribeFeatureType-request that fetches the * necessary schemas for all feature types that are queried in the given {@link GetFeature} * request. * * @param request * @return the URL-encoded parameter part of a KVP-DescribeFeatureType request */ private String buildDescribeFTRequest( GetFeature request ) { Set<QualifiedName> ftNames = new HashSet<QualifiedName>(); Map<String, URI> nsBindings = new HashMap<String, URI>(); // get all requested feature types Query[] queries = request.getQuery(); for ( Query query : queries ) { QualifiedName[] typeNames = query.getTypeNames(); for ( QualifiedName name : typeNames ) { ftNames.add( name ); } } Iterator<QualifiedName> ftNameIter = ftNames.iterator(); StringBuffer typeNameSb = new StringBuffer( ftNameIter.next().getAsString() ); while ( ftNameIter.hasNext() ) { typeNameSb.append( ',' ); typeNameSb.append( ftNameIter.next().getAsString() ); } // get all used namespace bindings for ( QualifiedName ftName : ftNames ) { nsBindings.put( ftName.getPrefix(), ftName.getNamespace() ); } StringBuffer nsParamSb = new StringBuffer( "xmlns(" ); Iterator<String> prefixIter = nsBindings.keySet().iterator(); String prefix = prefixIter.next(); nsParamSb.append( prefix ); nsParamSb.append( '=' ); nsParamSb.append( nsBindings.get( prefix ) ); while ( prefixIter.hasNext() ) { nsParamSb.append( ',' ); prefix = prefixIter.next(); nsParamSb.append( prefix ); nsParamSb.append( '=' ); nsParamSb.append( nsBindings.get( prefix ) ); } nsParamSb.append( ')' ); // build KVP-DescribeFeatureType-request StringBuffer sb = new StringBuffer( "SERVICE=WFS" ); sb.append( "&VERSION=1.1.0" ); sb.append( "&REQUEST=DescribeFeatureType" ); // append TYPENAME parameter sb.append( "&TYPENAME=" ); sb.append( typeNameSb ); // append NAMESPACE parameter sb.append( "&NAMESPACE=" ); sb.append( nsParamSb.toString() ); return sb.toString(); } /** * Transforms a {@link GetFeature} request depending on the requested virtual format. * * @param request * GetFeature request to be transformed * @param format * requested (virtual) output format * @return transformed GetFeature requested * @throws OGCWebServiceException * if transformation script could not be loaded or transformation failed */ private GetFeature transformGetFeature( GetFeature request, FormatType format ) throws OGCWebServiceException { // TODO: cache XSLTDocument XSLTDocument xsl = new XSLTDocument(); try { xsl.load( format.getInFilter().toURL() ); } catch ( Exception e ) { String msg = Messages.getMessage( "WFS_PREPROCESS_XSL_FILE_ERROR", format.getValue(), format.getInFilter().toString(), e ); LOG.logError( msg ); throw new OGCWebServiceException( getClass().getName(), msg ); } XMLFragment xml = null; try { xml = XMLFactory.export( request ); xml = xsl.transform( xml, format.getInFilter().toASCIIString(), null, null ); } catch ( Exception e ) { String msg = Messages.getMessage( "WFS_PREPROCESS_XSL_ERROR", format.getValue(), e ); LOG.logError( msg ); throw new OGCWebServiceException( getClass().getName(), msg ); } return GetFeature.create( request.getId(), xml.getRootElement() ); } /** * Sends the given {@link FeatureCollection} as GML to the given * {@link HttpServletResponse} object. * * @param fc * feature collection to send * @param httpResponse * servlet response object to write to * @param schemaURL * URL to schema document (DescribeFeatureType request) * @param suppressXLinks * true, if no XLinks must be used in the output, false otherwise */ private void sendGMLResponse( FeatureCollection fc, HttpServletResponse httpResponse, String schemaURL, boolean suppressXLinks ) { try { httpResponse.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() ); OutputStream os = httpResponse.getOutputStream(); GMLFeatureAdapter featureAdapter = new GMLFeatureAdapter( suppressXLinks, schemaURL ); featureAdapter.export( fc, os, CharsetUtils.getSystemCharset() ); } catch ( Exception e ) { LOG.logError( "Error sending GetFeature response (GML) to client.", e ); } } /** * Sends the given {@link FeatureCollection} as a serialized Java object to the given * {@link HttpServletResponse} object. * * @param fc * feature collection to send * @param httpResponse * servlet response object to write to */ private void sendBinaryResponse( FeatureCollection fc, HttpServletResponse httpResponse ) { try { OutputStream os = httpResponse.getOutputStream(); ObjectOutputStream oos = new ObjectOutputStream( os ); oos.writeObject( fc ); oos.flush(); } catch ( IOException e ) { LOG.logError( "Error sending GetFeature response (binary) to client.", e ); } } /** * Transforms a {@link FeatureCollection} to the given format using XSLT and sends it to the * specified {@link HttpServletResponse} object. * * @param fc * feature collection to send * @param httpResponse * servlet response object to write to * @param format * requested format */ private void sendTransformedResponse( FeatureCollection fc, HttpServletResponse httpResponse, FormatType format ) throws OGCWebServiceException { GMLFeatureAdapter featureAdapter = new GMLFeatureAdapter( true ); // estimate that each feature is 2000 byte ByteArrayOutputStream bos = new ByteArrayOutputStream( fc.size() * 2000 ); try { // export result feature collection as GML to enable transformation // into another (XML) format featureAdapter.export( fc, bos, CharsetUtils.getSystemCharset() ); } catch ( Exception e ) { LOG.logError( "could not export feature collection to GML", e ); throw new OGCWebServiceException( getClass().getName(), "could not export feature collection to GML; " + e.getMessage() ); } // TODO: cache Transformer Transformer xsl = null; try { StreamSource src = new StreamSource( new File( format.getOutFilter() ) ); xsl = TransformerFactory.newInstance().newTransformer( src ); } catch ( Exception e ) { String msg = Messages.getMessage( "WFS_POSTPROCESS_XSL_FILE_ERROR", format.getValue(), format.getOutFilter().toString(), e ); LOG.logError( msg ); throw new OGCWebServiceException( msg ); } try { if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { FileUtils.writeToFile( "WFS_GetFeature_Result.xml", new String( bos.toByteArray() ) ); LOG.logDebug( "Feature collection has been written to: WFS_GetFeature_Result.xml" ); } // transform GML into desired output format and write back to client ByteArrayInputStream bis = new ByteArrayInputStream( bos.toByteArray() ); StreamSource src = new StreamSource( bis ); String type = format.getValue().split( ";" )[0]; httpResponse.setContentType( type + "; charset=" + CharsetUtils.getSystemCharset() ); StreamResult res = new StreamResult( httpResponse.getOutputStream() ); xsl.transform( src, res ); } catch ( Exception e ) { String msg = Messages.getMessage( "WFS_POSTPROCESS_XSL_ERROR", format.getValue(), e ); LOG.logError( msg, e ); throw new OGCWebServiceException( getClass().getName(), msg ); } } /** * Performs a {@link Transaction} request and sends the response to the given * {@link HttpServletResponse} object. * * @param service * WFService instance to be used * @param request * Transaction request to be performed * @param httpResponse * servlet response object to write to * @throws OGCWebServiceException */ private void performTransaction( WFService service, Transaction request, HttpServletResponse httpResponse ) throws OGCWebServiceException { WFSConfiguration config = (WFSConfiguration) service.getCapabilities(); FormatType format = determineFormat( request, config ); // perform pre-processing if necessary (XSLT) if ( format.isVirtual() ) { request = transformTransaction( request, format ); } TransactionResponse response = (TransactionResponse) service.doService( request ); try { httpResponse.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() ); XMLFragment document = XMLFactory.export( response ); document.write( httpResponse.getOutputStream() ); } catch ( IOException e ) { LOG.logError( "Error sending Transaction response to client.", e ); } } /** * Transforms a {@link Transaction} request depending on the requested virtual format. * * @param request * Transaction request to be transformed * @param formatType * requested (virtual) output format * @return transformed Transaction * @throws OGCWebServiceException * if transformation script could not be loaded or transformation failed */ private Transaction transformTransaction( Transaction request, FormatType format ) throws OGCWebServiceException { // TODO: cache XSLTDocument XSLTDocument xsl = new XSLTDocument(); try { xsl.load( format.getInFilter().toURL() ); } catch ( Exception e ) { String msg = Messages.getMessage( "WFS_PREPROCESS_XSL_FILE_ERROR", format.getValue(), format.getInFilter().toString(), e ); LOG.logError( msg, e ); throw new OGCWebServiceException( getClass().getName(), msg ); } XMLFragment xml = null; try { //xml = XMLFactory.export( request ); xml = request.getSourceDocument(); if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { xml.prettyPrint( System.out ); } } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new OGCWebServiceException( getClass().getName(), e.getMessage() ); } // transform Transaction request try { xml = xsl.transform( xml, format.getInFilter().toASCIIString(), null, null ); if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { xml.prettyPrint( System.out ); } } catch ( Exception e ) { String msg = Messages.getMessage( "WFS_PREPROCESS_XSL_ERROR", format.getInFilter().toString(), e ); LOG.logError( msg, e ); throw new OGCWebServiceException( getClass().getName(), msg ); } try { request = Transaction.create( request.getId(), xml.getRootElement() ); } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new OGCWebServiceException( getClass().getName(), e.getMessage() ); } return request; } /** * Determines whether the response to the given {@link GetFeature} request may use XLinks or * not. * <p> * If the requested feature types belong to schemas that are configured to suppress XLink * output, this method returns true, otherwise false. If both suppressXLink=true and * suppressXLink=false apply, an OCGWebServiceException is thrown. * * @param request * @return true, if the response document must not contain XLinks, false otherwise * @throws OGCWebServiceException */ private boolean suppressXLinkOutput( GetFeature request, WFService service ) throws OGCWebServiceException { int suppressXLinkOutput = 0; int useXLinkOutput = 0; Query[] queries = request.getQuery(); for ( int i = 0; i < queries.length; i++ ) { Query query = queries[i]; QualifiedName[] typeNames = query.getTypeNames(); for ( int j = 0; j < typeNames.length; j++ ) { QualifiedName typeName = typeNames[j]; MappedFeatureType ft = service.getMappedFeatureType( typeName ); if ( ft == null ) { throw new OGCWebServiceException( this.getClass().getName(), "Internal error: WFS does not know feature type '" + typeName + "'." ); } if ( ft.getGMLSchema().suppressXLinkOutput() ) { suppressXLinkOutput++; } else { useXLinkOutput++; } } } if ( suppressXLinkOutput > 0 && useXLinkOutput > 0 ) { throw new OGCWebServiceException( this.getClass().getName(), "Invalid request / configuration - " + "suppressXLinkOutput=true + suppressXLinkOutput=false at the same time." ); } if ( suppressXLinkOutput > 0 ) { return true; } return false; } private FormatType determineFormat( GetFeature request, WFSConfiguration config ) throws OGCWebServiceException { Query firstQuery = request.getQuery()[0]; QualifiedName ftName = firstQuery.getTypeNames()[0]; WFSFeatureType wfsFT = config.getFeatureTypeList().getFeatureType( ftName ); if ( wfsFT == null ) { String msg = Messages.getMessage( "WFS_QUERY_UNKNOWN_FEATURETYPE", ftName ); throw new OGCWebServiceException( getClass().getName(), msg ); } String requestedFormat = request.getOutputFormat(); FormatType format = wfsFT.getOutputFormat( requestedFormat ); if ( format == null ) { String msg = Messages.getMessage( "WFS_QUERY_UNSUPPORTED_FORMAT", requestedFormat, ftName ); throw new OGCWebServiceException( getClass().getName(), msg ); } return format; } private FormatType determineFormat( DescribeFeatureType request, WFSConfiguration config ) throws OGCWebServiceException { // NOTE: this cannot cope with a mix of virtual and real features QualifiedName ftName = null; if ( request.getTypeNames().length > 0 ) { ftName = request.getTypeNames()[0]; } else { ftName = config.getFeatureTypeList().getFeatureTypes()[0].getName(); } WFSFeatureType wfsFT = config.getFeatureTypeList().getFeatureType( ftName ); if ( wfsFT == null ) { String msg = Messages.getMessage( "WFS_QUERY_UNKNOWN_FEATURETYPE", ftName ); throw new OGCWebServiceException( getClass().getName(), msg ); } String requestedFormat = request.getOutputFormat(); FormatType format = wfsFT.getOutputFormat( requestedFormat ); if ( format == null ) { String msg = Messages.getMessage( "WFS_QUERY_UNSUPPORTED_FORMAT", requestedFormat, ftName ); throw new OGCWebServiceException( getClass().getName(), msg ); } return format; } private FormatType determineFormat( Transaction request, WFSConfiguration config ) throws OGCWebServiceException { FormatType format = null; WFSFeatureType wfsFT = config.getFeatureTypeList().getFeatureTypes()[0]; List<TransactionOperation> list = request.getOperations(); TransactionOperation op = list.get( 0 ); if ( op instanceof Insert ) { QualifiedName qn = ( (Insert) op ).getAffectedFeatureTypes().get( 0 ); wfsFT = config.getFeatureTypeList().getFeatureType( qn ); if ( wfsFT == null ) { throw new OGCWebServiceException( Messages.getMessage( "WFS_INSERT_UNSUPPORTED_FT", qn ) ); } } else if ( op instanceof Update ) { QualifiedName qn = ( (Update) op ).getAffectedFeatureTypes().get( 0 ); wfsFT = config.getFeatureTypeList().getFeatureType( qn ); if ( wfsFT == null ) { throw new OGCWebServiceException( Messages.getMessage( "WFS_UPDATE_UNSUPPORTED_FT", qn ) ); } } else if ( op instanceof Delete ) { QualifiedName qn = ( (Delete) op ).getAffectedFeatureTypes().get( 0 ); wfsFT = config.getFeatureTypeList().getFeatureType( qn ); if ( wfsFT == null ) { throw new OGCWebServiceException( Messages.getMessage( "WFS_DELETE_UNSUPPORTED_FT", qn ) ); } } FormatType[] formats = wfsFT.getOutputFormats(); for ( int i = 0; i < formats.length; i++ ) { format = formats[i]; if ( format.getInFilter() != null ) { break; } } return format; } } /* ******************************************************************** Changes to this class. What the people have been up to: $Log: WFSHandler.java,v $ Revision 1.49 2006/10/20 15:35:41 poth now transform GetFeature responses (feature collections) will be written directly into the output stream to enable other transformation results than XML Revision 1.48 2006/10/17 20:31:18 poth *** empty log message *** Revision 1.47 2006/10/11 20:30:45 mschneider Added GML application schema reference in output (xsi:schemaLocation). Revision 1.46 2006/10/11 17:59:24 mschneider Added code for schema reference in GetFeature-responses. Not activated yet. Revision 1.45 2006/10/05 17:00:13 poth debuging changed for transforming transactions Revision 1.44 2006/10/05 12:54:29 poth bug bix - determining FormatType for a Transaction Revision 1.43 2006/10/05 11:26:45 mschneider Improved javadoc. Added handling for uncatched Exceptions. Revision 1.42 2006/10/05 11:07:28 mschneider Restructured. Implemented better checks for preprocessing. Revision 1.41 2006/10/02 16:51:17 mschneider Javadoc fixes. Revision 1.40 2006/07/23 10:05:54 poth setting content type for Http responses enhanced by adding charset (for mime types text/plain and text/xml) Revision 1.39 2006/07/21 14:06:30 mschneider GetCapabilities responses should respect requested sections now. Revision 1.38 2006/07/12 14:46:15 poth comment footer added ********************************************************************** */