001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data;
017:
018: import java.io.IOException;
019: import java.util.Set;
020:
021: /**
022: * The controller for Transaction with FeatureStore.
023: *
024: * <p>
025: * Shapefiles, databases, etc. are safely modified with the assistance of this
026: * interface. Transactions are also to provide authorization when working with
027: * locked features.
028: * </p>
029: *
030: * <p>
031: * All operations are considered to be working against a Transaction.
032: * Transaction.AUTO_COMMIT is used to represent an immidiate mode where
033: * requests are immidately commited.
034: * </p>
035: *
036: * <p>
037: * For more information please see DataStore and FeatureStore.
038: * </p>
039: *
040: * <p>
041: * Example Use:
042: * </p>
043: * <pre><code>
044: * Transaction t = new DefaultTransaction("handle");
045: * t.putProperty( "hint", new Integer(7) );
046: * try {
047: * FeatureStore road = (FeatureStore) store.getFeatureSource("road");
048: * FeatureStore river = (FeatureStore) store.getFeatureSource("river");
049: *
050: * road.setTransaction( t );
051: * river.setTransaction( t );
052: *
053: * t.addAuthorization( lockID ); // provide authoriztion
054: * road.removeFeatures( filter ); // operate against transaction
055: * river.removeFeature( filter ); // operate against transaction
056: *
057: * t.commit(); // commit operations
058: * }
059: * catch (IOException io){
060: * t.rollback(); // cancel operations
061: * }
062: * finally {
063: * t.close(); // free resources
064: * }
065: * </code></pre>
066: * <p>
067: * Example code walkthrough (from the perspective of Transaction):
068: * </p>
069: * <ol>
070: * <li>A new transaction is created (an instanceof DefaultTransaction with a handle)</li>
071: * <li>A hint is provided using Transaction.putProperty( key, value )</li>
072: * <li>Transaction is provided to two FeatureStores, this may result
073: * in Transaction.State instances being registered</li>
074: * <ul>
075: * <li>TransactionStateDiff (stored by DataStore):
076: * Used for in memory locking is used by many DataStore's
077: * (like ShapefileDataStore).
078: * Lazy creation by AbstractDataStore.state(transaction).
079: * </li>
080: * <li>JDBCTransactionState (stored by ConnectionPool):
081: * Used to manage connection rollback/commit.
082: * Lazy creation as part of JDBCDataStore.getConnection(transaction).
083: * </li>
084: * <li>InProcessLockingManager.FeatureLock (stored by LockingManger):
085: * Used for per transaction FeatureLocks, used to free locked features
086: * on Transaction commit/rollback.
087: * </li>
088: * </ul>
089: * These instances of Transaction state may make use of any hint provided
090: * to Transaction.putProperty( key, value ) when they are connected with
091: * Transaction.State.setTransaction( transaction ).
092: * <li>t.addAuthorization(lockID) is called, each Transaction.State has its
093: * addAuthroization(String) callback invoked with the value of lockID</li>
094: * <li>FeatureStore.removeFeatures methods are called on the two DataStores.
095: * <ul>
096: * <li>PostgisFeatureStore.removeFeatures(fitler) handles operation
097: * without delegation.
098: * </li>
099: * <li>Most removeFeature(filter) implementations use the implementation
100: * provided by AbstractFeatureStore which delegates to FeatureWriter.
101: * </li>
102: * </ul>
103: * Any of these operations may make use of the
104: * Transaction.putProperty( key, value ).
105: * <li>The transaction is commited, all of the Transaction.State methods have
106: * there Transaction.State.commit() methods called gicing them a chance
107: * to applyDiff maps, or commit various connections.
108: * </li>
109: * <li>The transaction is closed, all of the Transaction.State methods have
110: * there Transaction.State.setTransaction( null ) called, giving them a
111: * chance to clean up diffMaps, or return connections to the pool.
112: * </li>
113: * </ol>
114: * @author Jody Garnett
115: * @author Chris Holmes, TOPP
116: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/api/src/main/java/org/geotools/data/Transaction.java $
117: * @version $Id: Transaction.java 23258 2006-12-06 19:30:14Z tmarti $
118: */
119: public interface Transaction {
120: /** Represents AUTO_COMMIT Mode */
121: static final Transaction AUTO_COMMIT = new AutoCommitTransaction();
122:
123: //
124: // External State
125: //
126: /**
127: * Retrive a Transaction property held by this transaction.
128: *
129: * <p>
130: * This may be used to provide hints to DataStore implementations, it
131: * operates as a blackboard for client, FeatureSource communication.
132: * </p>
133: *
134: * <p>
135: * If this proves successful addAuthorization/getAuthorization will be
136: * replaced with this mechanism.
137: * </p>
138: */
139: Object getProperty(Object key);
140:
141: /**
142: * List of Authorizations IDs held by this transaction.
143: *
144: * <p>
145: * This list is reset by the next call to commit() or rollback().
146: * </p>
147: *
148: * <p>
149: * Authorization IDs are used to provide FeatureLock support.
150: * </p>
151: *
152: * @return List of Authorization IDs
153: */
154: Set getAuthorizations();
155:
156: /**
157: * Allows FeatureSource to squirel away information( and callbacks ) for
158: * later.
159: *
160: * <p>
161: * The most common example is a JDBC DataStore saving the required
162: * connection for later operations.
163: * </p>
164: * <pre><code>
165: * ConnectionState implements State {
166: * public Connection conn;
167: * public addAuthorization() {}
168: * public commit(){ conn.commit(); }
169: * public rollback(){ conn.rollback(); }
170: * }
171: * </code></pre>
172: *
173: * <p>
174: * putState will call State.setTransaction( transaction ) to allow State a
175: * chance to configure itself.
176: * </p>
177: *
178: * @param key Key used to externalize State
179: * @param state Externalized State
180: */
181: void putState(Object key, State state);
182:
183: /**
184: * Allows FeatureSources to clean up information ( and callbacks ) they
185: * earlier provided.
186: *
187: * <p>
188: * Care should be taken when using shared State to not remove State
189: * required by another FeatureSources.
190: * </p>
191: *
192: * <p>
193: * removeState will call State.setTransaction( null ) to allow State a
194: * chance cleanup after itself.
195: * </p>
196: *
197: * @param key Key that was used to externalize State
198: */
199: void removeState(Object key);
200:
201: /**
202: * Allows DataStores to squirel away information( and callbacks ) for
203: * later.
204: *
205: * <p>
206: * The most common example is a JDBC DataStore saving the required
207: * connection for later operations.
208: * </p>
209: *
210: * @return Current State externalized by key, or <code>null</code> if not
211: * found
212: */
213: State getState(Object key);
214:
215: //
216: // Flow Control
217: //
218:
219: /**
220: * Makes all transactions made since the previous commit/rollback
221: * permanent.
222: *
223: * <p>
224: * FeatureSources will need to issue any changes notifications using a
225: * FeatureEvent.FEATURES_CHANGED to all FeatureSources with the same
226: * typeName and a different Transaction. FeatureSources with the same
227: * Transaction will of been notified of changes as the FeaureWriter made
228: * them.
229: * </p>
230: *
231: * @throws DataSourceException if there are any datasource errors.
232: *
233: * @see #setAutoCommit(boolean)
234: */
235: void commit() throws IOException;
236:
237: /**
238: * Undoes all transactions made since the last commit or rollback.
239: *
240: * <p>
241: * FeatureSources will need to issue any changes notifications using a
242: * FeatureEvent.FEATURES_CHANGED. This will need to be issued to all
243: * FeatureSources with the same typeName and Transaction.
244: * </p>
245: *
246: * @throws DataSourceException if there are problems with the datasource.
247: * @throws UnsupportedOperationException if the rollback method is not
248: * supported by this datasource.
249: *
250: * @see #setAutoCommit(boolean)
251: */
252: void rollback() throws IOException;
253:
254: //
255: // Locking Support
256: //
257:
258: /**
259: * Provides an Authorization ID for this Transaction.
260: *
261: * <p>
262: * All proceeding modifyFeatures,removeFeature, unLockFeatures, refreshLock
263: * and ReleaseLock operations will make use of the provided authorization.
264: * </p>
265: *
266: * <p>
267: * Authorization is only maintained until the this Transaction is commited
268: * or rolledback.
269: * </p>
270: *
271: * <p>
272: * That is operations will only succeed if affected features either:
273: * </p>
274: *
275: * <ul>
276: * <li>
277: * not locked
278: * </li>
279: * <li>
280: * locked with the provided authID
281: * </li>
282: * </ul>
283: *
284: * <p>
285: * Authorization ID is provided as a String, rather than a FeatureLock, to
286: * account for across process lock use.
287: * </p>
288: *
289: * @param authID
290: */
291: void addAuthorization(String authID) throws IOException;
292:
293: /**
294: * Provides a Transaction property for this Transasction.
295: *
296: * <p>
297: * All proceeding FeatureSource (for FeatureReader/Writer) operations may
298: * make use of the provided property.
299: * </p>
300: */
301: void putProperty(Object key, Object value) throws IOException;
302:
303: /**
304: * Provides an opportunity for a Transaction to free an State it maintains.
305: * <p>
306: * This method should call State.setTransaction( null ) on all State it
307: * maintains.
308: * </p>
309: * <p>
310: * It is hoped that FeatureStore implementations that have externalized
311: * their State with the transaction take the opportunity to revert to
312: * Transction.AUTO_COMMIT.
313: * </p>
314: * @throws IOException
315: */
316: void close() throws IOException;
317:
318: /**
319: * DataStore implementations can use this interface to externalize the
320: * state they require to implement Transaction Support.
321: *
322: * <p>
323: * The commit and rollback methods will be called as required. The
324: * intension is that several DataStores can share common transaction state
325: * (example: Postgis DataStores sharing a connection to the same
326: * database).
327: * </p>
328: *
329: * @author jgarnett, Refractions Reasearch Inc.
330: * @version CVS Version
331: *
332: * @see org.geotools.data
333: */
334: static public interface State {
335: /**
336: * Provides configuration information for Transaction.State
337: *
338: * <p>
339: * setTransaction is called with non null <code>transaction</code> when
340: * Transaction.State is <code>putState</code> into a Transaction. This
341: * tranasction will be used to determine correct event notification.
342: * </p>
343: *
344: * <p>
345: * setTransaction is called with <code>null</code> when removeState is
346: * called (usually during Transaction.close() ).
347: * </p>
348: *
349: * @param transaction
350: */
351: void setTransaction(Transaction transaction);
352:
353: /**
354: * Call back used for Transaction.setAuthorization()
355: */
356: void addAuthorization(String AuthID) throws IOException;
357:
358: /**
359: * Call back used for Transaction.commit()
360: */
361: void commit() throws IOException;
362:
363: /**
364: * Call back used for Transaction.rollback()
365: */
366: void rollback() throws IOException;
367: }
368: }
|