001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-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.jdbc;
017:
018: import java.io.IOException;
019: import java.sql.Connection;
020: import java.sql.ResultSet;
021: import java.sql.SQLException;
022: import java.util.logging.Level;
023:
024: import javax.sql.DataSource;
025:
026: import org.geotools.data.jdbc.datasource.ManageableDataSource;
027: import org.geotools.data.jdbc.fidmapper.FIDMapperFactory;
028: import org.geotools.feature.AttributeType;
029:
030: /**
031: * This JDBCDataStore is able to take advantage of additonal functionality
032: * provided by JDBC2 level drivers - for example ConnectionPools.
033: *
034: * <p>
035: * This class provides a default implementation of a JDBC data store. Support
036: * for vendor specific JDBC data stores can be easily added to Geotools by
037: * subclassing this class and overriding the hooks provided.
038: * </p>
039: *
040: * <p>
041: * At a minimum subclasses should implement the following methods:
042: *
043: * <ul>
044: * <li>
045: * {@link #buildAttributeType(ResultSet) buildAttributeType(ResultSet)} - This
046: * should be overriden to construct an attribute type that represents any
047: * column types not supported by the default implementation, such as geometry
048: * columns.
049: * </li>
050: * <li>
051: * {@link #getGeometryAttributeIO(AttributeType, QueryData)
052: * getGeometryAttributeIO(AttributeType, QueryData)} - Should be overriden to
053: * provide a way to read/write geometries into the format of the database
054: * </li>
055: * </ul>
056: * </p>
057: *
058: * <p>
059: * Additionally subclasses can optionally override the following:
060: *
061: * <ul>
062: * <li>
063: * Use a specific FIDMapperFactory by overriding the {@link
064: * #buildFIDMapperFactory(JDBCDataStoreConfig)
065: * buildFIDMapperFactory(JDBCDataStoreConfig)} method, and eventually disallow
066: * user overrides by throwing an {@link
067: * java.lang.UnsupportedOperationException UnsupportedOperationException} in
068: * the {@link #setFIDMapperFactory(FIDMapperFactory) setFidMapperFactory()}
069: * method.
070: * </li>
071: * <li>
072: * {@link #allowTable(String) allowTable} - Used to determine whether a table
073: * name should be exposed as a feature type.
074: * </li>
075: * <li>
076: * {@link #determineSRID(String,String) determineSRID} - Used to determine the
077: * SpatialReference ID of a geometry column in a table.
078: * </li>
079: * <li>
080: * {@link #buildSQLQuery(String,AttributeType[],Filter,boolean)
081: * buildSQLQuery()} - Sub classes can override this to build a custom SQL
082: * query.
083: * </li>
084: * <li>
085: * {@link #getResultSetType(boolean) getResultSetType} if the standard result
086: * set type is not satisfactory/does not work with a normal FORWARD_ONLY
087: * resultset type
088: * </li>
089: * <li>
090: * {@link #getConcurrency(boolean) getConcurrency} to set the level of
091: * concurrency for the result set used to read/write the database
092: * </li>
093: * </ul>
094: * </p>
095: *
096: * <p>
097: * Additionally subclasses may want to set the value of:
098: *
099: * <ul>
100: * <li>
101: * sqlNameEscape - character (String) to surround names of SQL objects to
102: * support mixed-case and non-English names.
103: * </li>
104: * </ul>
105: * </p>
106: *
107: * @author Amr Alam, Refractions Research
108: * @author Jody Garnett, Refractions Research
109: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/jdbc/src/main/java/org/geotools/data/jdbc/JDBC2DataStore.java $
110: */
111: public abstract class JDBC2DataStore extends JDBC1DataStore {
112:
113: protected DataSource dataSource;
114:
115: /**
116: * Construct a JDBCDataStore with ConnectionPool and associated
117: * configuration.
118: *
119: * @param connectionPool
120: * @param config
121: *
122: * @throws IOException
123: */
124: public JDBC2DataStore(DataSource dataSource,
125: JDBCDataStoreConfig config) throws IOException {
126: super (config);
127: this .dataSource = dataSource;
128: }
129:
130: /**
131: * Create a connection for your JDBC1 database
132: */
133: protected Connection createConnection() throws SQLException {
134: return dataSource.getConnection();
135: }
136:
137: protected void finalize() throws Throwable {
138: if (dataSource != null) {
139: LOGGER
140: .severe("There's code using JDBC based datastore and "
141: + "not disposing them. This may lead to temporary loss of database connections. "
142: + "Please make sure all data access code calls DataStore.dispose() "
143: + "before freeing all references to it");
144: dispose();
145: }
146:
147: }
148:
149: public void dispose() {
150: if (dataSource != null
151: && dataSource instanceof ManageableDataSource) {
152: try {
153: ManageableDataSource mds = (ManageableDataSource) dataSource;
154: dataSource = null;
155: mds.close();
156: } catch (SQLException e) {
157: // it's ok, we did our best..
158: LOGGER.log(Level.FINE, "Could not close dataSource", e);
159: }
160: }
161: }
162: }
|