001 //$Header: /deegreerepository/deegree/src/org/deegree/io/datastore/Datastore.java,v 1.28 2007/01/16 13:58:34 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.io.datastore; 037 038 import java.util.ArrayList; 039 import java.util.Collection; 040 import java.util.List; 041 import java.util.Set; 042 043 import org.deegree.datatypes.QualifiedName; 044 import org.deegree.framework.log.ILogger; 045 import org.deegree.framework.log.LoggerFactory; 046 import org.deegree.framework.trigger.TriggerProvider; 047 import org.deegree.i18n.Messages; 048 import org.deegree.io.datastore.schema.MappedFeatureType; 049 import org.deegree.io.datastore.schema.MappedGMLSchema; 050 import org.deegree.io.datastore.schema.content.MappingGeometryField; 051 import org.deegree.model.crs.CoordinateSystem; 052 import org.deegree.model.crs.UnknownCRSException; 053 import org.deegree.model.feature.Feature; 054 import org.deegree.model.feature.FeatureCollection; 055 import org.deegree.model.filterencoding.Filter; 056 import org.deegree.ogcwebservices.wfs.WFService; 057 import org.deegree.ogcwebservices.wfs.operation.Lock; 058 import org.deegree.ogcwebservices.wfs.operation.LockFeature; 059 import org.deegree.ogcwebservices.wfs.operation.Query; 060 061 /** 062 * A datastore implementation must extend this class. 063 * <p> 064 * Describes the access to a datastore that encapsulates the access to a database or file. The 065 * accessible objects are {@link Feature} instances. Primarily, datastores are used as persistence 066 * layer by the {@link WFService} class. 067 * 068 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> 069 * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </a> 070 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </a> 071 * @author last edited by: $Author: mschneider $ 072 * 073 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $ 074 */ 075 public abstract class Datastore { 076 077 private static final TriggerProvider TP = TriggerProvider.create( Datastore.class ); 078 079 private static final ILogger LOG = LoggerFactory.getLogger( Datastore.class ); 080 081 private Collection<MappedGMLSchema> schemas = new ArrayList<MappedGMLSchema>( 10 ); 082 083 private DatastoreConfiguration config; 084 085 /** 086 * Returns the datastore specific annotation parser. 087 * 088 * @return the datastore specific annotation parser 089 */ 090 public abstract AnnotationDocument getAnnotationParser(); 091 092 /** 093 * Configures the datastore with the supplied configuration. 094 * 095 * @param config 096 * configuration 097 * @throws DatastoreException 098 */ 099 @SuppressWarnings("unused") 100 public void configure( DatastoreConfiguration config ) 101 throws DatastoreException { 102 this.config = config; 103 } 104 105 /** 106 * Returns the configuration parameters of the datastore. 107 * 108 * @return the configuration parameters of the datastore 109 */ 110 public DatastoreConfiguration getConfiguration() { 111 return this.config; 112 } 113 114 /** 115 * Adds the given GML application schema to the set of schemas that are handled by this 116 * datastore instance. 117 * <p> 118 * Note that this method may be called several times for every GML schema that uses this 119 * datastore instance. 120 * 121 * @param schema 122 * GML application schema to bind 123 * @throws DatastoreException 124 */ 125 @SuppressWarnings("unused") 126 public void bindSchema( MappedGMLSchema schema ) 127 throws DatastoreException { 128 this.schemas.add( schema ); 129 } 130 131 /** 132 * Returns the GML application schemas that are handled by this datastore. 133 * 134 * @return the GML application schemas that are handled by this datastore 135 */ 136 public MappedGMLSchema[] getSchemas() { 137 return this.schemas.toArray( new MappedGMLSchema[this.schemas.size()] ); 138 } 139 140 /** 141 * Returns the feature type with the given name. 142 * 143 * @param ftName 144 * name of the feature type 145 * @return the feature type with the given name, or null if the <code>Datastore</code> does 146 * not this feature type 147 */ 148 public MappedFeatureType getFeatureType( QualifiedName ftName ) { 149 MappedFeatureType ft = null; 150 MappedGMLSchema[] schemas = getSchemas(); 151 for ( int i = 0; i < schemas.length; i++ ) { 152 ft = schemas[i].getFeatureType( ftName ); 153 if ( ft != null ) { 154 break; 155 } 156 } 157 return ft; 158 } 159 160 /** 161 * Closes the datastore so it can free dependent resources. 162 * 163 * @throws DatastoreException 164 */ 165 public abstract void close() 166 throws DatastoreException; 167 168 /** 169 * Performs a query against the datastore. 170 * 171 * @param query 172 * query to be performed 173 * @param rootFts 174 * the root feature types that are queried, more than one type means that the types 175 * are joined 176 * @return requested feature instances 177 * @throws DatastoreException 178 * @throws UnknownCRSException 179 */ 180 public abstract FeatureCollection performQuery( final Query query, final MappedFeatureType[] rootFts ) 181 throws DatastoreException, UnknownCRSException; 182 183 /** 184 * Performs a query against the datastore (in the given transaction context). 185 * 186 * @param query 187 * query to be performed 188 * @param rootFts 189 * the root feature types that are queried, more than one type means that the types 190 * are joined 191 * @param context 192 * context (used to specify the JDBCConnection, for example) 193 * @return requested feature instances 194 * @throws DatastoreException 195 * @throws UnknownCRSException 196 */ 197 public abstract FeatureCollection performQuery( final Query query, final MappedFeatureType[] rootFts, 198 final DatastoreTransaction context ) 199 throws DatastoreException, UnknownCRSException; 200 201 /** 202 * Determines the ids of all features to be locked by the given parts of a {@link LockFeature} 203 * request, this includes all descendant and super features of the targeted features as well. 204 * 205 * @param requestParts 206 * the parts of a <code>LockFeature</code> request that this <code>Datastore</code> 207 * is responsible for 208 * @return the ids of all features that have to be locked 209 * @throws DatastoreException 210 */ 211 public Set<FeatureId> determineFidsToLock( @SuppressWarnings("unused") 212 List<Lock> requestParts ) 213 throws DatastoreException { 214 throw new DatastoreException( Messages.getMessage( "DATASTORE_METHOD_UNSUPPORTED", this.getClass().getName(), 215 "#determineFeaturesToLock( LockFeature )" ) ); 216 } 217 218 /** 219 * Acquires transactional access to the datastore instance. There's only one active transaction 220 * per datastore allowed. 221 * 222 * @return transaction object that allows to perform transactions operations on the datastore 223 * @throws DatastoreException 224 */ 225 public DatastoreTransaction acquireTransaction() 226 throws DatastoreException { 227 throw new DatastoreException( Messages.getMessage( "DATASTORE_METHOD_UNSUPPORTED", this.getClass().getName(), 228 "#acquireTransaction()" ) ); 229 } 230 231 /** 232 * Returns the transaction to the datastore. This makes the transaction available to other 233 * clients again (via {@link #acquireTransaction()}). Underlying resources (such as 234 * JDBCConnections are freed). 235 * <p> 236 * The transaction should be terminated, i.e. {@link DatastoreTransaction#commit()} or 237 * {@link DatastoreTransaction#rollback()} must have been called before. 238 * 239 * @param ta 240 * the DatastoreTransaction to be returned 241 * @throws DatastoreException 242 */ 243 public void releaseTransaction( @SuppressWarnings("unused") 244 DatastoreTransaction ta ) 245 throws DatastoreException { 246 throw new DatastoreException( Messages.getMessage( "DATASTORE_METHOD_UNSUPPORTED", this.getClass().getName(), 247 "#releaseTransaction()" ) ); 248 } 249 250 /** 251 * Transforms the incoming {@link Query} so that the {@link CoordinateSystem} of all spatial 252 * arguments (BBOX, etc.) in the {@link Filter} match the SRS of the targeted 253 * {@link MappingGeometryField}s. 254 * <p> 255 * NOTE: If this transformation can be performed by the backend (e.g. by Oracle Spatial), this 256 * method should be overwritten to return the original input {@link Query}. 257 * 258 * @param query 259 * query to be transformed 260 * @return query with spatial arguments transformed to target SRS 261 */ 262 protected Query transformQuery( Query query ) { 263 LOG.logDebug( "Transforming query." ); 264 Object[] result = TP.doPreTrigger( this, query ); 265 return (Query) result[0]; 266 } 267 268 /** 269 * Transforms the {@link FeatureCollection} so that the geometries of all contained geometry 270 * properties use the requested SRS. 271 * 272 * @param fc 273 * feature collection to be transformed 274 * @param targetSRS 275 * requested SRS 276 * @return transformed FeatureCollection 277 */ 278 protected FeatureCollection transformResult( FeatureCollection fc, String targetSRS ) { 279 LOG.logDebug( "Transforming result to SRS '" + targetSRS + "'." ); 280 Object[] result = TP.doPostTrigger( this, fc, targetSRS ); 281 return (FeatureCollection) result[0]; 282 } 283 284 /** 285 * Returns whether the datastore is capable of performing a native coordinate transformation 286 * (using an SQL function call for example) into the given SRS. 287 * <p> 288 * <code>Datastore</code> implementations capable of performing native coordinate 289 * transformations must override this class. 290 * 291 * @param targetSRS 292 * target spatial reference system (usually "EPSG:XYZ") 293 * @return true, if the datastore can perform the coordinate transformation, false otherwise 294 */ 295 protected boolean canTransformTo( @SuppressWarnings("unused") 296 String targetSRS ) { 297 return false; 298 } 299 }