001: /*
002: * Licensed under the X license (see http://www.x.org/terms.htm)
003: */
004: package org.ofbiz.minerva.pool.jdbc;
005:
006: import java.sql.Connection;
007: import java.sql.DriverManager;
008: import java.sql.SQLException;
009: import java.util.Properties;
010:
011: import org.apache.log4j.Logger;
012: import org.ofbiz.minerva.pool.ObjectPool;
013: import org.ofbiz.minerva.pool.PoolObjectFactory;
014: import org.ofbiz.minerva.pool.cache.ObjectCache;
015:
016: /**
017: * Object factory that creates java.sql.Connections. This is meant for use
018: * outside a J2EE/JTA environment - servlets alone, client/server, etc. If
019: * you're interested in creating transactional-aware connections, see
020: * XAConnectionFactory, which complies with the JDBC 2.0 standard extension.
021: * @see org.ofbiz.minerva.pool.jdbc.xa.XAConnectionFactory
022: *
023: * @author Aaron Mulder (ammulder@alumni.princeton.edu)
024: */
025: public class JDBCConnectionFactory extends PoolObjectFactory {
026:
027: private String url;
028: private Properties props;
029: private String userName;
030: private String password;
031: private int psCacheSize = 10;
032: private ObjectPool pool;
033:
034: private static Logger log = Logger
035: .getLogger(JDBCConnectionFactory.class);
036:
037: /**
038: * Creates a new factory. You must configure it with JDBC properties
039: * before you can use it.
040: */
041: public JDBCConnectionFactory() {
042: }
043:
044: /**
045: * Sets the JDBC URL used to create new connections.
046: */
047: public void setConnectURL(String url) {
048: this .url = url;
049: }
050:
051: /**
052: * Gets the JDBC URL used to create new connections.
053: */
054: public String getConnectURL() {
055: return url;
056: }
057:
058: /**
059: * Sets the JDBC Propeties used to create new connections.
060: * This is optional, and will only be used if present.
061: */
062: public void setConnectProperties(Properties props) {
063: this .props = props;
064: }
065:
066: /**
067: * Gets the JDBC Properties used to create new connections.
068: */
069: public Properties getConnectProperties() {
070: return props;
071: }
072:
073: /**
074: * Sets the JDBC user name used to create new connections.
075: * This is optional, and will only be used if present.
076: */
077: public void setUser(String userName) {
078: this .userName = userName;
079: }
080:
081: /**
082: * Gets the JDBC user name used to create new connections.
083: */
084: public String getUser() {
085: return userName;
086: }
087:
088: /**
089: * Sets the JDBC password used to create new connections.
090: * This is optional, and will only be used if present.
091: */
092: public void setPassword(String password) {
093: this .password = password;
094: }
095:
096: /**
097: * Gets the JDBC password used to create new connections.
098: */
099: public String getPassword() {
100: return password;
101: }
102:
103: /**
104: * Sets the number of PreparedStatements to be cached for each
105: * Connection. Your DB product may impose a limit on the number
106: * of open PreparedStatements. The default value is 10.
107: */
108: public void setPSCacheSize(int size) {
109: psCacheSize = size;
110: }
111:
112: /**
113: * Gets the number of PreparedStatements to be cached for each
114: * Connection. The default value is 10.
115: */
116: public int getPSCacheSize() {
117: return psCacheSize;
118: }
119:
120: /**
121: * Validates that connection properties were set (at least a URL).
122: */
123: public void poolStarted(ObjectPool pool) {
124: if (log.isDebugEnabled())
125: log.debug("Starting");
126:
127: super .poolStarted(pool);
128: if (url == null) {
129: log.error("Must specify JDBC connection URL");
130: throw new IllegalStateException(
131: "Must specify JDBC connection URL to "
132: + getClass().getName());
133: }
134: this .pool = pool;
135: }
136:
137: /**
138: * Cleans up.
139: */
140: public void poolClosing(ObjectPool pool) {
141: if (log.isDebugEnabled())
142: log.debug("Stopping");
143:
144: super .poolClosing(pool);
145: this .pool = null;
146: }
147:
148: /**
149: * Creates a new JDBC Connection.
150: */
151: public Object createObject(Object parameters) throws Exception {
152:
153: log.debug("Opening new connection");
154:
155: try {
156: if (userName != null && userName.length() > 0)
157: return DriverManager.getConnection(url, userName,
158: password);
159: else if (props != null)
160: return DriverManager.getConnection(url, props);
161: else
162: return DriverManager.getConnection(url);
163: } catch (SQLException e) {
164: log.error("SQL Error", e);
165: throw e;
166: }
167: }
168:
169: /**
170: * Wraps the connection with a ConnectionInPool.
171: * @see org.ofbiz.minerva.pool.jdbc.ConnectionInPool
172: */
173: public Object prepareObject(Object pooledObject) {
174: Connection con = (Connection) pooledObject;
175: ConnectionInPool wrapper = new ConnectionInPool(con);
176: wrapper.setPSCacheSize(psCacheSize);
177: return wrapper;
178: }
179:
180: /**
181: * Returns the original connection from a ConnectionInPool.
182: * @see org.ofbiz.minerva.pool.jdbc.ConnectionInPool
183: */
184: public Object translateObject(Object clientObject) {
185: return ((ConnectionInPool) clientObject)
186: .getUnderlyingConnection();
187: }
188:
189: /**
190: * Closes all outstanding work for the connection, rolls it back, and
191: * returns the underlying connection to the pool.
192: */
193: public Object returnObject(Object clientObject) {
194: ConnectionInPool wrapper = (ConnectionInPool) clientObject;
195: Connection con = wrapper.getUnderlyingConnection();
196: try {
197: wrapper.reset();
198: } catch (SQLException e) {
199: pool.markObjectAsInvalid(clientObject);
200: }
201: return con;
202: }
203:
204: /**
205: * Closes a connection.
206: */
207: public void deleteObject(Object pooledObject) {
208: Connection con = (Connection) pooledObject;
209: try {
210: con.rollback();
211: } catch (SQLException ignored) {
212: }
213:
214: // Removed all the cached PreparedStatements for this Connection
215: ObjectCache cache = (ObjectCache) ConnectionInPool.psCaches
216: .remove(con);
217: if (cache != null)
218: cache.close();
219:
220: try {
221: con.close();
222: } catch (SQLException ignored) {
223: }
224: }
225: }
226:
227: /*
228: vim:tabstop=3:et:shiftwidth=3
229: */
|