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.sql.DataSource;
008:
009: import org.apache.commons.dbcp.BasicDataSource;
010: import org.apache.commons.dbcp.BasicDataSourceFactory;
011: import org.apache.commons.dbcp.ConnectionFactory;
012: import org.apache.commons.dbcp.DriverManagerConnectionFactory;
013: import org.apache.commons.dbcp.PoolableConnectionFactory;
014: import org.apache.commons.pool.KeyedObjectPoolFactory;
015: import org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory;
016: import org.apache.commons.pool.impl.GenericObjectPool;
017: import org.geotools.data.AbstractDataStoreFactory;
018: import org.geotools.data.DataStore;
019: import org.geotools.data.DataStoreFactorySpi;
020: import org.geotools.data.jdbc.ConnectionManager;
021: import org.geotools.data.jdbc.DataSourceManager;
022: import org.geotools.data.jdbc.JDBCDataStore;
023:
024: /**
025: * Factory will connect to the H2 database, internally this class makes use of a DBCP
026: * dataSource supporting Pooling (please see H2DirectStoreFactory if you want to use
027: * your own DataSource).
028: * <p>
029: * Please see the public static Params for a description of what is needed to connect to this
030: * beast. The information is available in a dynamic fashion via getPrametersInfo() if you
031: * are building a user interface on the fly.
032: * </ul>
033: * <p>
034: * Notes and examples:
035: * <ul>
036: * <li>H2 configuration is in your local home directory - .h2.server.properties
037: * <br>C:\Documents and Settings\[username]\.h2.server.properties
038: * <li>url:
039: * <br>"jdbc:h2:test"
040: * <br>"jdbc:h2:test;IFEXISTS=TRUE"
041: * <br>"jdbc:h2:file:/data/sample;IFEXISTS=TRUE"
042: * <br>"jdbc:h2:mem:test_mem"
043: * <li>user: "sa" (for system administrator)
044: * <li>passowrd: ""
045: * </ul>
046: * <p>
047: * Implementation note: This implementation <b>does not use a DBTYPE</b> parameter, instead the URL_PARAM
048: * is checked to ensure it starts with "jdbc:h2".
049: *
050: * @author Jody Garnett
051: */
052: public class H2DBCPDataStoreFactory extends AbstractDataStoreFactory {
053:
054: private static final String H2_DRIVER_CLASSNAME = "org.h2.Driver";
055: public static final Param URL_PARAM = new Param("url",
056: String.class, "Example: jdbc:h2:file:/data/sample", true,
057: "jdbc:h2:mem:test_mem");
058: public static final Param USERNAME_PARAM = new Param("user",
059: String.class, "Username", true, "sa");
060: public static final Param PASSWORD_PARAM = new Param("user",
061: String.class, "Password", true, "");
062:
063: public DataStore createDataStore(Map params) throws IOException {
064: String url = (String) URL_PARAM.lookUp(params);
065: String user = (String) USERNAME_PARAM.lookUp(params);
066: String password = (String) PASSWORD_PARAM.lookUp(params);
067:
068: url += ";IFEXISTS=TRUE"; // do not create if it does not exist
069: DataSource dataSource = aquireDataSource(url, user, password);
070:
071: // ConnectionManager if needed to bridge to old JDBCDataStore code
072: // ConnectionManager connectionManager = new DataSourceManager( dataSource );
073: JDBCDataStore dataStore = new JDBCDataStore();
074: dataStore.setDataSource(dataSource);
075:
076: return dataStore;
077: }
078:
079: public DataStore createNewDataStore(Map params) throws IOException {
080: String url = (String) URL_PARAM.lookUp(params);
081: String user = (String) USERNAME_PARAM.lookUp(params);
082: String password = (String) PASSWORD_PARAM.lookUp(params);
083:
084: DataSource dataSource = aquireDataSource(url, user, password);
085:
086: JDBCDataStore dataStore = new JDBCDataStore();
087: dataStore.setDataSource(dataSource);
088:
089: return dataStore;
090: }
091:
092: private DataSource aquireDataSource(String url, String user,
093: String password) {
094: BasicDataSource dataSource = new BasicDataSource();
095: dataSource.setDriverClassName(H2_DRIVER_CLASSNAME);
096: dataSource.setUrl(url);
097: dataSource.setUsername(user);
098: dataSource.setPassword(password);
099: dataSource.setAccessToUnderlyingConnectionAllowed(true);
100:
101: final int CONNECTIONS = 10;
102: dataSource.setMaxActive(CONNECTIONS);
103: dataSource.setMaxIdle(CONNECTIONS / 2);
104: dataSource.setMinIdle(CONNECTIONS / 4);
105:
106: final int PREPAIRED_STATEMENTS = 5; // should aquire from Hint
107: dataSource.setPoolPreparedStatements(PREPAIRED_STATEMENTS != 0);
108: if (PREPAIRED_STATEMENTS != 0) {
109: dataSource
110: .setMaxOpenPreparedStatements(PREPAIRED_STATEMENTS);
111: }
112: return dataSource;
113: }
114:
115: /** This is good example code - but not sure how to hook it up? */
116: private PoolableConnectionFactory createConnectionFactory(
117: String url, String user, String password) {
118: ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
119: url, user, password);
120:
121: GenericObjectPool connectionPool = new GenericObjectPool();
122:
123: KeyedObjectPoolFactory statementPool = new GenericKeyedObjectPoolFactory(
124: null);
125: final boolean defaultReadOnly = false;
126: final boolean defaultAutoCommit = true;
127: final String validationQuery = null;
128:
129: return new PoolableConnectionFactory(connectionFactory,
130: connectionPool, statementPool, validationQuery,
131: defaultReadOnly, defaultAutoCommit);
132: }
133:
134: public String getDescription() {
135: return "The H2 Database is Java and can be used for temporary, or persistent storage.";
136: }
137:
138: public String getDisplayName() {
139: return "H2";
140: }
141:
142: public Param[] getParametersInfo() {
143: return new Param[] { URL_PARAM, USERNAME_PARAM, PASSWORD_PARAM };
144: }
145:
146: public boolean isAvailable() {
147: try {
148: Class.forName(H2_DRIVER_CLASSNAME);
149: } catch (ClassNotFoundException e) {
150: return false;
151: }
152: return true;
153: }
154:
155: }
|