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 (Tue, 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 }