    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    }