001 //$Header: /deegreerepository/deegree/src/org/deegree/ogcwebservices/wfs/WFService.java,v 1.46 2007/03/14 14:43:44 mschneider Exp $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.ogcwebservices.wfs; 037 038 import static java.util.Arrays.asList; 039 import static java.util.Collections.disjoint; 040 import static org.deegree.i18n.Messages.get; 041 import static org.deegree.ogcbase.ExceptionCode.INVALID_UPDATESEQUENCE; 042 import static org.deegree.ogcbase.ExceptionCode.VERSIONNEGOTIATIONFAILED; 043 044 import java.util.List; 045 import java.util.Map; 046 047 import org.deegree.datatypes.QualifiedName; 048 import org.deegree.framework.log.ILogger; 049 import org.deegree.framework.log.LoggerFactory; 050 import org.deegree.framework.trigger.TriggerProvider; 051 import org.deegree.io.datastore.LockManager; 052 import org.deegree.io.datastore.schema.MappedFeatureType; 053 import org.deegree.ogcwebservices.OGCWebService; 054 import org.deegree.ogcwebservices.OGCWebServiceException; 055 import org.deegree.ogcwebservices.OGCWebServiceRequest; 056 import org.deegree.ogcwebservices.getcapabilities.Operation; 057 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities; 058 import org.deegree.ogcwebservices.wfs.configuration.WFSConfiguration; 059 import org.deegree.ogcwebservices.wfs.operation.DescribeFeatureType; 060 import org.deegree.ogcwebservices.wfs.operation.GetFeature; 061 import org.deegree.ogcwebservices.wfs.operation.GetFeatureWithLock; 062 import org.deegree.ogcwebservices.wfs.operation.GetGmlObject; 063 import org.deegree.ogcwebservices.wfs.operation.LockFeature; 064 import org.deegree.ogcwebservices.wfs.operation.WFSGetCapabilities; 065 import org.deegree.ogcwebservices.wfs.operation.transaction.Transaction; 066 import org.deegree.owscommon.OWSDomainType; 067 068 /** 069 * This class implements access to the methods defined in the OGC WFS 1.1.0 specification. 070 * 071 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a> 072 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 073 * @author last edited by: $Author: mschneider $ 074 * 075 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $ 076 * 077 * @see OGCWebService 078 */ 079 public class WFService implements OGCWebService { 080 081 private static final ILogger LOG = LoggerFactory.getLogger( WFService.class ); 082 083 /** Only OGC standard version currently implemented by this service. */ 084 public static final String VERSION = "1.1.0"; 085 086 private static final TriggerProvider TP = TriggerProvider.create( WFService.class ); 087 088 private WFSConfiguration configuration; 089 090 // shared instance that handles all GetFeature requests to this service 091 private GetFeatureHandler getFeatureHandler; 092 093 // shared instance that handles all DescribeFeatureType requests to this service 094 private DescribeFeatureTypeHandler describeFTHandler; 095 096 // shared instance that handles all LockFeature requests to this service 097 private LockFeatureHandler lockFeatureHandler; 098 099 private GetGmlObjectHandler getGmlObjectHandler; 100 101 /** 102 * Creates a new instance of <code>WFService</code> with the given configuration. 103 * 104 * @param configuration 105 * @throws OGCWebServiceException 106 */ 107 WFService( WFSConfiguration configuration ) throws OGCWebServiceException { 108 this.configuration = configuration; 109 this.getFeatureHandler = new GetFeatureHandler( this ); 110 this.describeFTHandler = new DescribeFeatureTypeHandler( this ); 111 this.lockFeatureHandler = new LockFeatureHandler( this ); 112 getGmlObjectHandler = new GetGmlObjectHandler( configuration ); 113 } 114 115 /** 116 * Returns the capabilities of the <code>WFService</code>. 117 * 118 * @return the capabilities, this is actually a <code>WFSConfiguration</code> instance 119 */ 120 public WFSCapabilities getCapabilities() { 121 return this.configuration; 122 } 123 124 /** 125 * Performs the handling of the passed OGCWebServiceEvent directly and returns the result to the calling class/ 126 * method. 127 * 128 * @param request 129 * WFS request to perform 130 * 131 * @throws OGCWebServiceException 132 */ 133 public Object doService( OGCWebServiceRequest request ) 134 throws OGCWebServiceException { 135 136 long ts = System.currentTimeMillis(); 137 request = (OGCWebServiceRequest) TP.doPreTrigger( this, request )[0]; 138 139 Object response = null; 140 if ( request instanceof WFSGetCapabilities ) { 141 validateGetCapabilitiesRequest( (WFSGetCapabilities) request ); 142 response = this.configuration; 143 } else if ( request instanceof GetFeatureWithLock ) { 144 response = this.lockFeatureHandler.handleRequest( (GetFeatureWithLock) request ); 145 } else if ( request instanceof GetFeature ) { 146 response = this.getFeatureHandler.handleRequest( (GetFeature) request ); 147 } else if ( request instanceof DescribeFeatureType ) { 148 response = this.describeFTHandler.handleRequest( (DescribeFeatureType) request ); 149 } else if ( request instanceof Transaction ) { 150 TransactionHandler handler = new TransactionHandler( this, (Transaction) request ); 151 response = handler.handleRequest(); 152 } else if ( request instanceof LockFeature ) { 153 response = this.lockFeatureHandler.handleRequest( (LockFeature) request ); 154 } else if ( request instanceof GetGmlObject ) { 155 response = getGmlObjectHandler.handleRequest( (GetGmlObject) request ); 156 } else { 157 String msg = "Unknown request type: " + request.getClass().getName(); 158 throw new OGCWebServiceException( getClass().getName(), msg ); 159 } 160 161 Object o = TP.doPostTrigger( this, response )[0]; 162 if ( LOG.isDebug() ) { 163 LOG.logDebug( "Using lockmanager instance: " + LockManager.getInstance() ); 164 LOG.logDebug( "WFS processing time for request type " + request.getClass().getSimpleName() + ": ", 165 Long.toString( ( System.currentTimeMillis() - ts ) ) ); 166 } 167 return o; 168 } 169 170 // throws exception if it's required by the spec 171 private void validateGetCapabilitiesRequest( WFSGetCapabilities request ) 172 throws OGCWebServiceException { 173 // version negotiation 174 if ( request.getAcceptVersions() != null && request.getAcceptVersions().length != 0 ) { 175 Operation op = configuration.getOperationsMetadata().getGetCapabilitiesOperation(); 176 OWSDomainType versions = op.getParameter( "AcceptVersions" ); 177 List<String> vs1 = asList( versions.getValues() ); 178 List<String> vs2 = asList( request.getAcceptVersions() ); 179 180 if ( disjoint( vs1, vs2 ) ) { 181 throw new OGCWebServiceException( get( "WFS_VERSION_NEGOTIATION_FAILED" ), VERSIONNEGOTIATIONFAILED ); 182 } 183 } 184 185 if ( request.getUpdateSequence() != null ) { 186 // check update sequences 187 String seq = configuration.getUpdateSequence(); 188 if ( !request.getUpdateSequence().equals( "" ) && seq.compareTo( request.getUpdateSequence() ) < 0 ) { 189 throw new OGCWebServiceException( "updatesequence", get( "UPDATESEQUENCE_INVALID" ), 190 INVALID_UPDATESEQUENCE ); 191 } 192 } 193 } 194 195 /** 196 * Returns a clone of the <code>WFService</code> instance. 197 * <p> 198 * Note that the configuration of the new service will refer to the same instance. 199 */ 200 @Override 201 public Object clone() { 202 203 WFService clone = null; 204 try { 205 clone = new WFService( configuration ); 206 } catch ( OGCWebServiceException e ) { 207 // can never happen 208 } 209 return clone; 210 } 211 212 /** 213 * Returns the <code>MappedFeatureType</code> with the given name. 214 * 215 * @param name 216 * name of the feature type 217 * @return the mapped feature type with the given name, or null if it is not known to this WFService instance 218 */ 219 public MappedFeatureType getMappedFeatureType( QualifiedName name ) { 220 return this.configuration.getMappedFeatureTypes().get( name ); 221 } 222 223 /** 224 * Returns a <code>Map</code> of the feature types that this WFS serves. 225 * 226 * @return keys: feature type names, values: mapped feature types 227 */ 228 public Map<QualifiedName, MappedFeatureType> getMappedFeatureTypes() { 229 return this.configuration.getMappedFeatureTypes(); 230 } 231 }