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: aionita $ 074 * 075 * @version $Revision: 23794 $, $Date: 2010-04-23 15:05:33 +0200 (Fr, 23 Apr 2010) $ 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 ( (GetFeature) request ).guessAllMissingNamespaces( this ); 147 response = this.getFeatureHandler.handleRequest( (GetFeature) request ); 148 } else if ( request instanceof DescribeFeatureType ) { 149 ( (DescribeFeatureType) request ).guessMissingNamespaces( this ); 150 response = this.describeFTHandler.handleRequest( (DescribeFeatureType) request ); 151 } else if ( request instanceof Transaction ) { 152 ( (Transaction) request ).guessMissingNamespaces( this ); 153 TransactionHandler handler = new TransactionHandler( this, (Transaction) request ); 154 response = handler.handleRequest(); 155 } else if ( request instanceof LockFeature ) { 156 ( (LockFeature) request ).guessMissingNamespaces( this ); 157 response = this.lockFeatureHandler.handleRequest( (LockFeature) request ); 158 } else if ( request instanceof GetGmlObject ) { 159 response = getGmlObjectHandler.handleRequest( (GetGmlObject) request ); 160 } else { 161 String msg = "Unknown request type: " + request.getClass().getName(); 162 throw new OGCWebServiceException( getClass().getName(), msg ); 163 } 164 165 Object o = TP.doPostTrigger( this, response )[0]; 166 if ( LOG.isDebug() ) { 167 LOG.logDebug( "Using lockmanager instance: " + LockManager.getInstance() ); 168 LOG.logDebug( "WFS processing time for request type " + request.getClass().getSimpleName() + ": ", 169 Long.toString( ( System.currentTimeMillis() - ts ) ) ); 170 } 171 return o; 172 } 173 174 // throws exception if it's required by the spec 175 private void validateGetCapabilitiesRequest( WFSGetCapabilities request ) 176 throws OGCWebServiceException { 177 // version negotiation 178 if ( request.getAcceptVersions() != null && request.getAcceptVersions().length != 0 ) { 179 Operation op = configuration.getOperationsMetadata().getGetCapabilitiesOperation(); 180 OWSDomainType versions = op.getParameter( "AcceptVersions" ); 181 List<String> vs1 = asList( versions.getValues() ); 182 List<String> vs2 = asList( request.getAcceptVersions() ); 183 184 if ( disjoint( vs1, vs2 ) ) { 185 throw new OGCWebServiceException( get( "WFS_VERSION_NEGOTIATION_FAILED" ), VERSIONNEGOTIATIONFAILED ); 186 } 187 } 188 189 if ( request.getUpdateSequence() != null ) { 190 // check update sequences 191 String seq = configuration.getUpdateSequence(); 192 if ( !request.getUpdateSequence().equals( "" ) && seq.compareTo( request.getUpdateSequence() ) < 0 ) { 193 throw new OGCWebServiceException( "updatesequence", get( "UPDATESEQUENCE_INVALID" ), 194 INVALID_UPDATESEQUENCE ); 195 } 196 } 197 } 198 199 /** 200 * Returns a clone of the <code>WFService</code> instance. 201 * <p> 202 * Note that the configuration of the new service will refer to the same instance. 203 */ 204 @Override 205 public Object clone() { 206 207 WFService clone = null; 208 try { 209 clone = new WFService( configuration ); 210 } catch ( OGCWebServiceException e ) { 211 // can never happen 212 } 213 return clone; 214 } 215 216 /** 217 * Returns the <code>MappedFeatureType</code> with the given name. 218 * 219 * @param name 220 * name of the feature type 221 * @return the mapped feature type with the given name, or null if it is not known to this WFService instance 222 */ 223 public MappedFeatureType getMappedFeatureType( QualifiedName name ) { 224 return this.configuration.getMappedFeatureTypes().get( name ); 225 } 226 227 /** 228 * Returns a <code>Map</code> of the feature types that this WFS serves. 229 * 230 * @return keys: feature type names, values: mapped feature types 231 */ 232 public Map<QualifiedName, MappedFeatureType> getMappedFeatureTypes() { 233 return this.configuration.getMappedFeatureTypes(); 234 } 235 }