001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049:
050: package org.jaffa.persistence.engines.jdbcengine.datasource;
051:
052: import com.javaexchange.dbConnectionBroker.DbConnectionBroker;
053: import java.io.IOException;
054: import java.sql.Connection;
055: import java.sql.SQLException;
056: import org.apache.log4j.Logger;
057:
058: /** This is a DbConnectionBroker based implementation of IConnectionFactory.
059: * DbConnectionBroker is a fairly proven and stable implemenation for database connection pooling.
060: * It requires 'dbConnectionBroker.jar' in the classpath.
061: *
062: * @author GautamJ
063: */
064: public class DbConnectionBrokerConnectionFactory implements
065: IConnectionFactory {
066:
067: private static final Logger log = Logger
068: .getLogger(DbConnectionBrokerConnectionFactory.class);
069:
070: // the DbConnectionBroker, used for pooling connections
071: private static DbConnectionBroker c_dbConnectionBroker = null;
072:
073: // **************************************
074: // Properties for this Connection Factory
075: // **************************************
076: private String m_driverClass;
077: private String m_url;
078: private String m_user;
079: private String m_password;
080: private Integer m_minimumConnections;
081: private Integer m_maximumConnections;
082: private String m_logFileName;
083: private Double m_maxConnTime;
084: private Boolean m_logAppend;
085: private Integer m_maxCheckoutSeconds;
086: private Integer m_debugLevel;
087:
088: /** Getter for property driverClass.
089: * @return Value of property driverClass.
090: */
091: public String getDriverClass() {
092: return m_driverClass;
093: }
094:
095: /** Setter for property driverClass.
096: * @param driverClass New value of property driverClass.
097: */
098: public void setDriverClass(String driverClass) {
099: if (driverClass == null || driverClass.length() == 0)
100: m_driverClass = null;
101: else
102: m_driverClass = driverClass;
103: }
104:
105: /** Getter for property url.
106: * @return Value of property url.
107: */
108: public String getUrl() {
109: return m_url;
110: }
111:
112: /** Setter for property url.
113: * @param url New value of property url.
114: */
115: public void setUrl(String url) {
116: if (url == null || url.length() == 0)
117: m_url = null;
118: else
119: m_url = url;
120: }
121:
122: /** Getter for property user.
123: * @return Value of property user.
124: */
125: public String getUser() {
126: return m_user;
127: }
128:
129: /** Setter for property user.
130: * @param user New value of property user.
131: */
132: public void setUser(String user) {
133: if (user == null || user.length() == 0)
134: m_user = null;
135: else
136: m_user = user;
137: }
138:
139: /** Getter for property password.
140: * @return Value of property password.
141: */
142: public String getPassword() {
143: return m_password;
144: }
145:
146: /** Setter for property password.
147: * @param password New value of property password.
148: */
149: public void setPassword(String password) {
150: if (password == null || password.length() == 0)
151: m_password = null;
152: else
153: m_password = password;
154: }
155:
156: /** Getter for property minimumConnections.
157: * @return Value of property minimumConnections.
158: */
159: public Integer getMinimumConnections() {
160: return m_minimumConnections;
161: }
162:
163: /** Setter for property minimumConnections.
164: * @param minimumConnections New value of property minimumConnections.
165: */
166: public void setMinimumConnections(Integer minimumConnections) {
167: m_minimumConnections = minimumConnections;
168: }
169:
170: /** Getter for property maximumConnections.
171: * @return Value of property maximumConnections.
172: */
173: public Integer getMaximumConnections() {
174: return m_maximumConnections;
175: }
176:
177: /** Setter for property maximumConnections.
178: * @param maximumConnections New value of property maximumConnections.
179: */
180: public void setMaximumConnections(Integer maximumConnections) {
181: m_maximumConnections = maximumConnections;
182: }
183:
184: /** Getter for property logFileName.
185: * @return Value of property logFileName.
186: */
187: public String getLogFileName() {
188: return m_logFileName;
189: }
190:
191: /** Setter for property logFileName.
192: * @param logFileName New value of property logFileName.
193: */
194: public void setLogFileName(String logFileName) {
195: if (logFileName == null || logFileName.length() == 0)
196: m_logFileName = null;
197: else
198: m_logFileName = logFileName;
199: }
200:
201: /** Getter for property maxConnTime.
202: * @return Value of property maxConnTime.
203: */
204: public Double getMaxConnTime() {
205: return m_maxConnTime;
206: }
207:
208: /** Setter for property maxConnTime.
209: * @param maxConnTime New value of property maxConnTime.
210: */
211: public void setMaxConnTime(Double maxConnTime) {
212: m_maxConnTime = maxConnTime;
213: }
214:
215: /** Getter for property logAppend.
216: * @return Value of property logAppend.
217: */
218: public Boolean getLogAppend() {
219: return m_logAppend;
220: }
221:
222: /** Setter for property logAppend.
223: * @param logAppend New value of property logAppend.
224: */
225: public void setLogAppend(Boolean logAppend) {
226: m_logAppend = logAppend;
227: }
228:
229: /** Getter for property maxCheckoutSeconds.
230: * @return Value of property maxCheckoutSeconds.
231: */
232: public Integer getMaxCheckoutSeconds() {
233: return m_maxCheckoutSeconds;
234: }
235:
236: /** Setter for property maxCheckoutSeconds.
237: * @param maxCheckoutSeconds New value of property maxCheckoutSeconds.
238: */
239: public void setMaxCheckoutSeconds(Integer maxCheckoutSeconds) {
240: m_maxCheckoutSeconds = maxCheckoutSeconds;
241: }
242:
243: /** Getter for property debugLevel.
244: * @return Value of property debugLevel.
245: */
246: public Integer getDebugLevel() {
247: return m_debugLevel;
248: }
249:
250: /** Setter for property debugLevel.
251: * @param debugLevel New value of property debugLevel.
252: */
253: public void setDebugLevel(Integer debugLevel) {
254: m_debugLevel = debugLevel;
255: }
256:
257: // **************************************
258: // Implementation methods
259: // **************************************
260:
261: /** Creates a connection using DbConnectionBroker.
262: * @throws SQLException if any SQL error occurs
263: * @throws IOException if any IO error occurs
264: * @return a Connection
265: */
266: public Connection createConnection() throws SQLException,
267: IOException {
268: if (c_dbConnectionBroker == null)
269: createDbConnectionBroker();
270:
271: Connection connection = c_dbConnectionBroker.getConnection();
272: if (connection == null) {
273: String str = "Could not acquire a connection from DbConnectionBroker. Try again.";
274: log.error(str);
275: throw new SQLException(str);
276: }
277:
278: if (log.isDebugEnabled())
279: log
280: .debug("Acquired a pooled Connection from DbConnectionBroker: "
281: + connection);
282:
283: return connection;
284: }
285:
286: /** Returns the connection back to the pool.
287: * @param connection The connection to return back to the pool.
288: * @throws SQLException if any SQL error occurs
289: * @throws IOException if any IO error occurs
290: */
291: public void freeConnection(Connection connection)
292: throws SQLException, IOException {
293: if (log.isDebugEnabled())
294: log
295: .debug("Freeing up the pooled Connection back to DbConnectionBroker: "
296: + connection);
297: c_dbConnectionBroker.freeConnection(connection);
298: }
299:
300: /** Returns a true if the Prepared (and Call) Statements are to be cached for a connection.
301: * This will return a true.
302: * @return a true if the Prepared (and Call) Statements are to be cached for a connection.
303: */
304: public boolean usePreparedStatementCaching() {
305: return true;
306: }
307:
308: private synchronized void createDbConnectionBroker()
309: throws IOException {
310: if (c_dbConnectionBroker == null) {
311: double maxConnTime = getMaxConnTime() != null ? getMaxConnTime()
312: .doubleValue()
313: : 1; // the connections will be reset every day
314: boolean logAppend = getLogAppend() != null ? getLogAppend()
315: .booleanValue() : true;
316: int maxCheckoutSeconds = getMaxCheckoutSeconds() != null ? getMaxCheckoutSeconds()
317: .intValue()
318: : 0; // this will turn off the option of recycling the Connection after x seconds (default is 60 seconds)
319: int debugLevel = getDebugLevel() != null ? getDebugLevel()
320: .intValue() : 2;
321:
322: c_dbConnectionBroker = new DbConnectionBroker(
323: getDriverClass(), getUrl(), getUser(),
324: getPassword(), getMinimumConnections().intValue(),
325: getMaximumConnections().intValue(),
326: getLogFileName(), maxConnTime, logAppend,
327: maxCheckoutSeconds, debugLevel);
328: if (log.isDebugEnabled())
329: log.debug("Created the DbConnectionBroker");
330: }
331: }
332:
333: }
|