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 }