001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/io/datastore/sql/transaction/SQLTransaction.java $
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.sql.transaction;
037    
038    import java.sql.Connection;
039    import java.sql.SQLException;
040    import java.util.List;
041    import java.util.Map;
042    
043    import org.deegree.framework.log.ILogger;
044    import org.deegree.framework.log.LoggerFactory;
045    import org.deegree.io.datastore.DatastoreException;
046    import org.deegree.io.datastore.DatastoreTransaction;
047    import org.deegree.io.datastore.FeatureId;
048    import org.deegree.io.datastore.schema.MappedFeatureType;
049    import org.deegree.io.datastore.sql.AbstractRequestHandler;
050    import org.deegree.io.datastore.sql.AbstractSQLDatastore;
051    import org.deegree.io.datastore.sql.TableAliasGenerator;
052    import org.deegree.io.datastore.sql.transaction.delete.DeleteHandler;
053    import org.deegree.io.datastore.sql.transaction.insert.InsertHandler;
054    import org.deegree.model.feature.Feature;
055    import org.deegree.model.feature.FeatureProperty;
056    import org.deegree.model.filterencoding.Filter;
057    import org.deegree.ogcbase.PropertyPath;
058    import org.deegree.ogcwebservices.wfs.operation.transaction.Native;
059    import org.deegree.ogcwebservices.wfs.operation.transaction.Transaction;
060    
061    /**
062     * Handles {@link Transaction} requests to SQL based datastores.
063     *
064     * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
065     * @author <a href="mailto:deshmukh@lat-lon.de">Anup Deshmukh</a>
066     * @author last edited by: $Author: mschneider $
067     *
068     * @version $Revision: 18544 $, $Date: 2009-07-20 16:14:38 +0200 (Mo, 20. Jul 2009) $
069     */
070    public class SQLTransaction extends AbstractRequestHandler implements DatastoreTransaction {
071    
072        private static final ILogger LOG = LoggerFactory.getLogger( SQLTransaction.class );
073    
074        /**
075         * Creates a new instance of <code>SQLTransaction</code> from the given parameters.
076         *
077         * @param datastore
078         * @param aliasGenerator
079         * @param conn
080         * @throws DatastoreException
081         */
082        public SQLTransaction( AbstractSQLDatastore datastore, TableAliasGenerator aliasGenerator, Connection conn )
083                                throws DatastoreException {
084            super( datastore, aliasGenerator, conn );
085            try {
086                conn.setAutoCommit( false );
087            } catch ( SQLException e ) {
088                String msg = "Unable to disable auto commit: " + e.getMessage();
089                LOG.logError( msg );
090                throw new DatastoreException( msg, e );
091            }
092        }
093    
094        /**
095         * Returns the underlying <code>AbstractSQLDatastore</code>.
096         *
097         * @return the underlying <code>AbstractSQLDatastore</code>
098         */
099        public AbstractSQLDatastore getDatastore() {
100            return this.datastore;
101        }
102    
103        /**
104         * Returns the underlying JDBC connection.
105         *
106         * @return the underlying JDBC connection
107         */
108        public Connection getConnection() {
109            return this.conn;
110        }
111    
112        /**
113         * Makes the changes persistent that have been performed in this transaction.
114         *
115         * @throws DatastoreException
116         */
117        public void commit()
118                                throws DatastoreException {
119            try {
120                conn.commit();
121            } catch ( SQLException e ) {
122                String msg = "Unable to commit transaction: " + e.getMessage();
123                LOG.logError( msg );
124                throw new DatastoreException( msg, e );
125            }
126        }
127    
128        /**
129         * Aborts the changes that have been performed in this transaction.
130         *
131         * @throws DatastoreException
132         */
133        public void rollback()
134                                throws DatastoreException {
135            try {
136                conn.rollback();
137            } catch ( SQLException e ) {
138                String msg = "Unable to rollback transaction: " + e.getMessage();
139                LOG.logError( msg );
140                throw new DatastoreException( msg, e );
141            }
142        }
143    
144        /**
145         * Returns the transaction instance so other clients may acquire a transaction (and underlying resources, such as
146         * JDBCConnections can be freed).
147         *
148         * @throws DatastoreException
149         */
150        public void release()
151                                throws DatastoreException {
152            this.datastore.releaseTransaction( this );
153        }
154    
155        /**
156         * Inserts the given feature instances into the datastore.
157         *
158         * @param features
159         * @return feature ids of the inserted (root) features
160         * @throws DatastoreException
161         */
162        public List<FeatureId> performInsert( List<Feature> features )
163                                throws DatastoreException {
164    
165            InsertHandler handler = new InsertHandler( this, this.aliasGenerator, this.conn );
166            List<FeatureId> fids = handler.performInsert( features );
167            return fids;
168        }
169    
170        /**
171         * Performs an update operation against the datastore.
172         *
173         * @param mappedFeatureType
174         *            feature type that is to be updated
175         * @param replacementProps
176         *            properties and their replacement values
177         * @param filter
178         *            selects the feature instances that are to be updated
179         * @param lockId
180         *            optional id of associated lock (may be null)
181         * @return number of updated feature instances
182         * @throws DatastoreException
183         */
184        public int performUpdate( MappedFeatureType mappedFeatureType, Map<PropertyPath, FeatureProperty> replacementProps,
185                                  Filter filter, String lockId )
186                                throws DatastoreException {
187    
188            UpdateHandler handler = new UpdateHandler( this, this.aliasGenerator, this.conn, lockId );
189            int updatedFeatures = handler.performUpdate( mappedFeatureType, replacementProps, filter );
190            return updatedFeatures;
191        }
192    
193        /**
194         * Performs a update (replace-style) operation against the datastore.
195         * 
196         * @param mappedFeatureType
197         *            feature type that is to be replaced
198         * @param replacementFeature
199         *            feature instance that will be used to replace the properties of the selected features
200         * @param filter
201         *            selects the feature instances that are to be replaced
202         * @param lockId
203         *            optional id of associated lock (may be null)
204         * @return number of replaced feature instances
205         * @throws DatastoreException
206         */
207        public int performUpdate( MappedFeatureType mappedFeatureType, Feature replacementFeature, Filter filter,
208                                  String lockId )
209                                throws DatastoreException {
210    
211            UpdateHandler handler = new UpdateHandler( this, this.aliasGenerator, this.conn, lockId );
212            int updatedFeatures = handler.performUpdate( mappedFeatureType, replacementFeature, filter );
213            return updatedFeatures;
214        }
215        
216        /**
217         * Deletes the features from the datastore that are matched by the given filter and type.
218         *
219         * @param mappedFeatureType
220         * @param filter
221         * @param lockId
222         *            optional id of associated lock (may be null)
223         * @return number of deleted feature instances
224         * @throws DatastoreException
225         */
226        public int performDelete( MappedFeatureType mappedFeatureType, Filter filter, String lockId )
227                                throws DatastoreException {
228    
229            DeleteHandler handler = new DeleteHandler( this, this.aliasGenerator, this.conn, lockId );
230            int deletedFeatures = handler.performDelete( mappedFeatureType, filter );
231            return deletedFeatures;
232        }
233    
234        /**
235         * Performs a 'native' operation against the datastore.
236         *
237         * @param operation
238         * @return number of processed feature instances.
239         * @throws DatastoreException
240         */
241        public int performNative( Native operation )
242                                throws DatastoreException {
243    
244            throw new UnsupportedOperationException( "Native operations are not supported." );
245        }
246    }