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: hrubach $ 072 * 073 * @version $Revision: 23693 $, $Date: 2010-04-20 14:33:55 +0200 (Di, 20 Apr 2010) $ 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 public static final int SRS_UNDEFINED = -1; 086 087 /** 088 * Returns the datastore specific annotation parser. 089 * 090 * @return the datastore specific annotation parser 091 */ 092 public abstract AnnotationDocument getAnnotationParser(); 093 094 /** 095 * Configures the datastore with the supplied configuration. 096 * 097 * @param config 098 * configuration 099 * @throws DatastoreException 100 */ 101 @SuppressWarnings("unused") 102 public void configure( DatastoreConfiguration config ) 103 throws DatastoreException { 104 this.config = config; 105 } 106 107 /** 108 * Returns the configuration parameters of the datastore. 109 * 110 * @return the configuration parameters of the datastore 111 */ 112 public DatastoreConfiguration getConfiguration() { 113 return this.config; 114 } 115 116 /** 117 * Adds the given GML application schema to the set of schemas that are handled by this 118 * datastore instance. 119 * <p> 120 * Note that this method may be called several times for every GML schema that uses this 121 * datastore instance. 122 * 123 * @param schema 124 * GML application schema to bind 125 * @throws DatastoreException 126 */ 127 @SuppressWarnings("unused") 128 public void bindSchema( MappedGMLSchema schema ) 129 throws DatastoreException { 130 this.schemas.add( schema ); 131 } 132 133 /** 134 * Returns the GML application schemas that are handled by this datastore. 135 * 136 * @return the GML application schemas that are handled by this datastore 137 */ 138 public MappedGMLSchema[] getSchemas() { 139 return this.schemas.toArray( new MappedGMLSchema[this.schemas.size()] ); 140 } 141 142 /** 143 * Returns the feature type with the given name. 144 * 145 * @param ftName 146 * name of the feature type 147 * @return the feature type with the given name, or null if the <code>Datastore</code> does 148 * not this feature type 149 */ 150 public MappedFeatureType getFeatureType( QualifiedName ftName ) { 151 MappedFeatureType ft = null; 152 MappedGMLSchema[] schemas = getSchemas(); 153 for ( int i = 0; i < schemas.length; i++ ) { 154 ft = schemas[i].getFeatureType( ftName ); 155 if ( ft != null ) { 156 break; 157 } 158 } 159 return ft; 160 } 161 162 /** 163 * Closes the datastore so it can free dependent resources. 164 * 165 * @throws DatastoreException 166 */ 167 public abstract void close() 168 throws DatastoreException; 169 170 /** 171 * Performs a query against the datastore. 172 * 173 * @param query 174 * query to be performed 175 * @param rootFts 176 * the root feature types that are queried, more than one type means that the types 177 * are joined 178 * @return requested feature instances 179 * @throws DatastoreException 180 * @throws UnknownCRSException 181 */ 182 public abstract FeatureCollection performQuery( final Query query, final MappedFeatureType[] rootFts ) 183 throws DatastoreException, UnknownCRSException; 184 185 /** 186 * Performs a query against the datastore (in the given transaction context). 187 * 188 * @param query 189 * query to be performed 190 * @param rootFts 191 * the root feature types that are queried, more than one type means that the types 192 * are joined 193 * @param context 194 * context (used to specify the JDBCConnection, for example) 195 * @return requested feature instances 196 * @throws DatastoreException 197 * @throws UnknownCRSException 198 */ 199 public abstract FeatureCollection performQuery( final Query query, final MappedFeatureType[] rootFts, 200 final DatastoreTransaction context ) 201 throws DatastoreException, UnknownCRSException; 202 203 /** 204 * Determines the ids of all features to be locked by the given parts of a {@link LockFeature} 205 * request, this includes all descendant and super features of the targeted features as well. 206 * 207 * @param requestParts 208 * the parts of a <code>LockFeature</code> request that this <code>Datastore</code> 209 * is responsible for 210 * @return the ids of all features that have to be locked 211 * @throws DatastoreException 212 */ 213 public Set<FeatureId> determineFidsToLock( @SuppressWarnings("unused") 214 List<Lock> requestParts ) 215 throws DatastoreException { 216 throw new DatastoreException( Messages.getMessage( "DATASTORE_METHOD_UNSUPPORTED", this.getClass().getName(), 217 "#determineFeaturesToLock( LockFeature )" ) ); 218 } 219 220 /** 221 * Acquires transactional access to the datastore instance. There's only one active transaction 222 * per datastore allowed. 223 * 224 * @return transaction object that allows to perform transactions operations on the datastore 225 * @throws DatastoreException 226 */ 227 public DatastoreTransaction acquireTransaction() 228 throws DatastoreException { 229 throw new DatastoreException( Messages.getMessage( "DATASTORE_METHOD_UNSUPPORTED", this.getClass().getName(), 230 "#acquireTransaction()" ) ); 231 } 232 233 /** 234 * Returns the transaction to the datastore. This makes the transaction available to other 235 * clients again (via {@link #acquireTransaction()}). Underlying resources (such as 236 * JDBCConnections are freed). 237 * <p> 238 * The transaction should be terminated, i.e. {@link DatastoreTransaction#commit()} or 239 * {@link DatastoreTransaction#rollback()} must have been called before. 240 * 241 * @param ta 242 * the DatastoreTransaction to be returned 243 * @throws DatastoreException 244 */ 245 public void releaseTransaction( @SuppressWarnings("unused") 246 DatastoreTransaction ta ) 247 throws DatastoreException { 248 throw new DatastoreException( Messages.getMessage( "DATASTORE_METHOD_UNSUPPORTED", this.getClass().getName(), 249 "#releaseTransaction()" ) ); 250 } 251 252 /** 253 * Transforms the incoming {@link Query} so that the {@link CoordinateSystem} of all spatial 254 * arguments (BBOX, etc.) in the {@link Filter} match the SRS of the targeted 255 * {@link MappingGeometryField}s. 256 * <p> 257 * NOTE: If this transformation can be performed by the backend (e.g. by Oracle Spatial), this 258 * method should be overwritten to return the original input {@link Query}. 259 * 260 * @param query 261 * query to be transformed 262 * @return query with spatial arguments transformed to target SRS 263 */ 264 protected Query transformQuery( Query query ) { 265 LOG.logDebug( "Transforming query." ); 266 Object[] result = TP.doPreTrigger( this, query ); 267 return (Query) result[0]; 268 } 269 270 /** 271 * Transforms the {@link FeatureCollection} so that the geometries of all contained geometry 272 * properties use the requested SRS. 273 * 274 * @param fc 275 * feature collection to be transformed 276 * @param targetSRS 277 * requested SRS 278 * @return transformed FeatureCollection 279 */ 280 protected FeatureCollection transformResult( FeatureCollection fc, String targetSRS ) { 281 LOG.logDebug( "Transforming result to SRS '" + targetSRS + "'." ); 282 Object[] result = TP.doPostTrigger( this, fc, targetSRS ); 283 return (FeatureCollection) result[0]; 284 } 285 286 /** 287 * Returns whether the datastore is capable of performing a native coordinate transformation 288 * (using an SQL function call for example) into the given SRS. 289 * <p> 290 * <code>Datastore</code> implementations capable of performing native coordinate 291 * transformations must override this class. 292 * 293 * @param targetSRS 294 * target spatial reference system (usually "EPSG:XYZ") 295 * @return true, if the datastore can perform the coordinate transformation, false otherwise 296 */ 297 protected boolean canTransformTo( @SuppressWarnings("unused") 298 String targetSRS ) { 299 return false; 300 } 301 }