001: package org.geotools.data.h2;
002:
003: import java.io.IOException;
004: import java.util.Collections;
005: import java.util.Map;
006:
007: import javax.naming.NamingException;
008: import javax.sql.DataSource;
009:
010: import org.apache.commons.dbcp.BasicDataSource;
011: import org.apache.commons.dbcp.BasicDataSourceFactory;
012: import org.apache.commons.dbcp.ConnectionFactory;
013: import org.apache.commons.dbcp.DriverManagerConnectionFactory;
014: import org.apache.commons.dbcp.PoolableConnectionFactory;
015: import org.apache.commons.pool.KeyedObjectPoolFactory;
016: import org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory;
017: import org.apache.commons.pool.impl.GenericObjectPool;
018: import org.geotools.data.AbstractDataStoreFactory;
019: import org.geotools.data.DataStore;
020: import org.geotools.data.DataStoreFactorySpi;
021: import org.geotools.data.jdbc.ConnectionManager;
022: import org.geotools.data.jdbc.DataSourceManager;
023: import org.geotools.data.jdbc.JDBCDataStore;
024: import org.geotools.factory.GeoTools;
025:
026: /**
027: * Factory will connect to the H2 database using a DataSource you provide.
028: * <p>
029: * If you don't know what that means please use H2DBCPDataStoreFactory (it will
030: * make use of the popular commons dbcp library as an implementation of DataSource).
031: * <p>
032: * Please see the public static Params for a description of what is needed to connect to this
033: * beast. The information is available in a dynamic fashion via getPrametersInfo() if you
034: * are building a user interface on the fly.
035: * <p>
036: * Please note that a data source name is required (even if you are not using JNDI) -
037: * it is good Java EE Manners to register your DataSource and this gives us a chance to
038: * check up on you, the name will also be used in log messages.
039: * </p>
040: * @author Jody Garnett
041: */
042: public class H2DirectDataStoreFactory extends AbstractDataStoreFactory {
043:
044: private static final String H2_DRIVER_CLASSNAME = "org.h2.Driver";
045: public static final Param DATASOURCE_NAME_PARAM = new Param(
046: "dataSourceName", String.class, "Name to look up via JNDI",
047: true);
048: public static final Param DATASOURCE_PARAM = new Param(
049: "dataSource", DataSource.class, "DataSource to use", false);
050:
051: public DataStore createDataStore(Map params) throws IOException {
052: String name = (String) DATASOURCE_NAME_PARAM.lookUp(params);
053: DataSource dataSource = (DataSource) DATASOURCE_PARAM
054: .lookUp(params);
055:
056: if (name == null) {
057: throw new IOException("DataSource name required");
058: }
059: if (dataSource == null) {
060: try {
061: dataSource = (DataSource) GeoTools.getInitialContext(
062: GeoTools.getDefaultHints()).lookup(name);
063: } catch (NamingException e) {
064: throw (IOException) new IOException(
065: "Could not locate DataSource:" + e)
066: .initCause(e);
067: }
068: } else {
069: try {
070: GeoTools.getInitialContext(GeoTools.getDefaultHints())
071: .bind(name, dataSource);
072: } catch (NamingException e) {
073: // log warning
074: }
075: }
076: // ConnectionManager if needed to bridge to old JDBCDataStore code
077: // ConnectionManager connectionManager = new DataSourceManager( dataSource );
078: JDBCDataStore dataStore = new JDBCDataStore();
079: dataStore.setDataSource(dataSource);
080:
081: return dataStore;
082: }
083:
084: public DataStore createNewDataStore(Map params) throws IOException {
085: throw new UnsupportedOperationException(
086: "You must provide an existing DataSource");
087: }
088:
089: private DataSource aquireDataSource(String url, String user,
090: String password) {
091: BasicDataSource dataSource = new BasicDataSource();
092: dataSource.setDriverClassName(H2_DRIVER_CLASSNAME);
093: dataSource.setUrl(url);
094: dataSource.setUsername(user);
095: dataSource.setPassword(password);
096: dataSource.setAccessToUnderlyingConnectionAllowed(true);
097:
098: final int CONNECTIONS = 10;
099: dataSource.setMaxActive(CONNECTIONS);
100: dataSource.setMaxIdle(CONNECTIONS / 2);
101: dataSource.setMinIdle(CONNECTIONS / 4);
102:
103: final int PREPAIRED_STATEMENTS = 5; // should aquire from Hint
104: dataSource.setPoolPreparedStatements(PREPAIRED_STATEMENTS != 0);
105: if (PREPAIRED_STATEMENTS != 0) {
106: dataSource
107: .setMaxOpenPreparedStatements(PREPAIRED_STATEMENTS);
108: }
109: return dataSource;
110: }
111:
112: /** This is good example code - but not sure how to hook it up? */
113: private PoolableConnectionFactory createConnectionFactory(
114: String url, String user, String password) {
115: ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
116: url, user, password);
117:
118: GenericObjectPool connectionPool = new GenericObjectPool();
119:
120: KeyedObjectPoolFactory statementPool = new GenericKeyedObjectPoolFactory(
121: null);
122: final boolean defaultReadOnly = false;
123: final boolean defaultAutoCommit = true;
124: final String validationQuery = null;
125:
126: return new PoolableConnectionFactory(connectionFactory,
127: connectionPool, statementPool, validationQuery,
128: defaultReadOnly, defaultAutoCommit);
129: }
130:
131: public String getDescription() {
132: return "Access to an registered H2 Database.";
133: }
134:
135: public String getDisplayName() {
136: return "H2 DataSource";
137: }
138:
139: public Param[] getParametersInfo() {
140: return new Param[] { DATASOURCE_NAME_PARAM, DATASOURCE_PARAM };
141: }
142:
143: public boolean isAvailable() {
144: try {
145: Class.forName(H2_DRIVER_CLASSNAME);
146: } catch (ClassNotFoundException e) {
147: return false;
148: }
149: return true;
150: }
151:
152: }
|