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.postgis;
017:
018: import java.io.IOException;
019: import java.sql.Connection;
020: import java.sql.SQLException;
021:
022: import javax.sql.DataSource;
023:
024: import org.geotools.data.DataSourceException;
025: import org.geotools.data.Query;
026: import org.geotools.data.Transaction;
027: import org.geotools.data.jdbc.ConnectionPool;
028: import org.geotools.data.jdbc.FeatureTypeHandler;
029: import org.geotools.data.jdbc.JDBCDataStoreConfig;
030: import org.geotools.data.jdbc.fidmapper.FIDMapperFactory;
031: import org.geotools.data.postgis.fidmapper.PostgisFIDMapperFactory;
032: import org.geotools.data.postgis.fidmapper.VersionedFIDMapperFactory;
033:
034: /**
035: * A postgis datastore subclass that provides extra accessors so that the versioned datastore can
036: * work.<br>
037: * This class is needed because this way all the JDBC datastore infrastructure can work without the
038: * need to break its assumptions.<br>
039: * For example, getSchema() usually returns a feature type that mimics the table structure, but for
040: * versioned data we have to return one that does not have the versioning columns.
041: *
042: * @author aaime
043: * @since 2.4
044: *
045: */
046: class WrappedPostgisDataStore extends PostgisDataStore {
047:
048: public WrappedPostgisDataStore(DataSource dataSource,
049: JDBCDataStoreConfig config, int optimizeMode)
050: throws IOException {
051: super (dataSource, config, optimizeMode);
052:
053: }
054:
055: public WrappedPostgisDataStore(DataSource dataSource,
056: String schema, String namespace, int optimizeMode)
057: throws IOException {
058: super (dataSource, schema, namespace, optimizeMode);
059:
060: }
061:
062: public WrappedPostgisDataStore(DataSource dataSource,
063: String schema, String namespace) throws IOException {
064: super (dataSource, schema, namespace);
065:
066: }
067:
068: public WrappedPostgisDataStore(DataSource dataSource,
069: String namespace) throws IOException {
070: super (dataSource, namespace);
071:
072: }
073:
074: public WrappedPostgisDataStore(DataSource dataSource)
075: throws IOException {
076: super (dataSource);
077:
078: }
079:
080: /**
081: * Overridden to store a versioned jdbc transaction state instead
082: */
083: public Connection getConnection(Transaction transaction)
084: throws IOException {
085: if (transaction != Transaction.AUTO_COMMIT) {
086: // we will need to save a JDBC connection is
087: // transaction.putState( connectionPool, JDBCState )
088: // throw new UnsupportedOperationException("Transactions not
089: // supported yet");
090:
091: VersionedJdbcTransactionState state;
092:
093: state = getVersionedJdbcTransactionState(transaction);
094: return state.getConnection();
095: }
096:
097: try {
098: return createConnection();
099: } catch (SQLException sqle) {
100: throw new DataSourceException("Connection failed:" + sqle,
101: sqle);
102: }
103: }
104:
105: /**
106: * Returns the versioned jdbc transaction state, eventually
107: *
108: * @param transaction
109: * @return
110: * @throws IOException
111: * @throws DataSourceException
112: */
113: protected VersionedJdbcTransactionState getVersionedJdbcTransactionState(
114: Transaction transaction) throws IOException,
115: DataSourceException {
116: synchronized (transaction) {
117: VersionedJdbcTransactionState state;
118: state = (VersionedJdbcTransactionState) transaction
119: .getState(this );
120:
121: if (state == null) {
122: try {
123: Connection conn = createConnection();
124: conn.setAutoCommit(requireAutoCommit());
125: if (getTransactionIsolation() != Connection.TRANSACTION_NONE) {
126: // for us, NONE means use the default, which is
127: // usually READ_COMMITTED
128: conn
129: .setTransactionIsolation(getTransactionIsolation());
130: }
131: state = new VersionedJdbcTransactionState(conn,
132: this );
133: transaction.putState(this , state);
134: } catch (SQLException eep) {
135: throw new DataSourceException("Connection failed:"
136: + eep, eep);
137: }
138: }
139: return state;
140: }
141: }
142:
143: protected FIDMapperFactory buildFIDMapperFactory(
144: JDBCDataStoreConfig config) {
145: return new VersionedFIDMapperFactory(
146: new PostgisFIDMapperFactory(config));
147: }
148:
149: public String[] propertyNames(Query query) throws IOException {
150: return super .propertyNames(query);
151: }
152:
153: public JDBCDataStoreConfig getConfig() {
154: return config;
155: }
156:
157: public FeatureTypeHandler getTypeHandler() {
158: return typeHandler;
159: }
160:
161: }
|