View Javadoc

1   /***
2    * @(#)IbatisService.java
3    * 
4    * JFoxSOAF, Service-Oriented Application Framework
5    * 
6    * Copyright(c) JFoxSOAF Team
7    * 
8    * Licensed under the GNU LGPL, Version 2.1 (the "License"); 
9    * you may not use this file except in compliance with the License. 
10   * You may obtain a copy of the License at  
11   * 
12   * http://www.gnu.org/copyleft/lesser.html
13   * 
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, 
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
17   * See the License for the specific language governing permissions and 
18   * limitations under the License. 
19   * 
20   * For more information, please visit:
21   * http://www.jfox.cn/confluence/display/JFoxSOAF/Home
22   * http://www.huihoo.org/jfox/jfoxsoaf
23   */
24  
25  package org.huihoo.jfox.soaf.services.jdbc;
26  
27  import java.sql.SQLException;
28  import java.util.Enumeration;
29  import java.util.Hashtable;
30  import java.util.Vector;
31  
32  import javax.sql.DataSource;
33  
34  import org.apache.commons.lang.BooleanUtils;
35  import org.apache.commons.lang.StringUtils;
36  import org.apache.commons.lang.math.NumberUtils;
37  import org.apache.commons.logging.Log;
38  import org.apache.commons.logging.LogFactory;
39  import org.huihoo.jfox.soaf.exception.DataSourceConfigurationException;
40  
41  import com.mchange.v2.c3p0.DataSources;
42  import com.mchange.v2.c3p0.PoolConfig;
43  
44  /***
45   * <p>
46   * C3P0 DataSource Factory
47   * </p>
48   * 
49   * @author <a href="mailto:founder_chen@yahoo.com.cn">Peter Cheng </a>
50   * @version $Revision: 1.6 $ $Date: 2005/05/22 06:49:48 $
51   * @version Revision: 1.0
52   */
53  
54  public class C3P0DataSourceFactory extends DataSourceFactory {
55  
56      private final Log logger = LogFactory.getLog(getClass());
57  
58      private DataSource dataSource;
59  
60      //  The configuration attributes for this {@link DataSourceFactory}.
61      private Hashtable attributes = new Hashtable();
62  
63      /***
64       * @see org.huihoo.jfox.soaf.services.jdbc.DataSourceFactory#getInstance()
65       * @return DataSource instance
66       * @throws DataSourceConfigurationException
67       */
68      public DataSource getInstance() throws DataSourceConfigurationException,
69              SQLException {
70          String jdbcDriverClass = (String) getAttribute(DatabaseConstant.JDBC_DRIVER_CLASS_NAME);
71          if (StringUtils.isEmpty(jdbcDriverClass)) {
72              logger
73                      .warn("No JDBC Driver class was specified by database.properties : "
74                              + DatabaseConstant.JDBC_DRIVER_CLASS_NAME);
75          } else {
76              try {
77                  Class.forName(jdbcDriverClass);
78              } catch (ClassNotFoundException e) {
79                  String errorMsg = "JDBC Driver class not found: "
80                          + jdbcDriverClass;
81                  logger.fatal(errorMsg);
82                  throw new DataSourceConfigurationException(errorMsg, e);
83              }
84          }
85  
86          // Set pool configuration
87          PoolConfig poolConfig = new PoolConfig();
88          String initPoolSize = (String) getAttribute(DatabaseConstant.JDBC_INIT_POOL_SIZE);
89  
90          if (!NumberUtils.isNumber(initPoolSize)) {
91              poolConfig
92                      .setInitialPoolSize(NumberUtils.stringToInt(initPoolSize));
93          }
94  
95          String minPoolSize = (String) getAttribute(DatabaseConstant.JDBC_MIN_POOL_SIZE);
96  
97          if (!NumberUtils.isNumber(minPoolSize)) {
98              poolConfig.setMinPoolSize(NumberUtils.stringToInt(minPoolSize));
99          }
100 
101         String maxPoolSize = (String) getAttribute(DatabaseConstant.JDBC_MAX_POOL_SIZE);
102 
103         if (!!NumberUtils.isNumber(maxPoolSize)) {
104             poolConfig.setMaxPoolSize(NumberUtils.stringToInt(maxPoolSize));
105         }
106 
107         String maxIdleTime = (String) getAttribute(DatabaseConstant.JDBC_MAX_IDLE_TIME);
108 
109         if (!NumberUtils.isNumber(maxIdleTime)) {
110             poolConfig.setMaxIdleTime(NumberUtils.stringToInt(maxIdleTime));
111         }
112 
113         String idleConnTestPeriod = (String) getAttribute(DatabaseConstant.C3P0_JDBC_IDLE_CONN_TEST_PERIOD);
114 
115         if (!NumberUtils.isNumber(maxIdleTime)) {
116             poolConfig.setIdleConnectionTestPeriod(NumberUtils
117                     .stringToInt(idleConnTestPeriod));
118         }
119 
120         String maxStatements = (String) getAttribute(DatabaseConstant.C3P0_JDBC_MAX_STATEMENTS);
121 
122         if (!NumberUtils.isNumber(maxStatements)) {
123             poolConfig.setMaxStatements(NumberUtils.stringToInt(maxStatements));
124         }
125 
126         String propertyCycle = (String) getAttribute(DatabaseConstant.C3P0_JDBC_PROPERTY_CYCLE);
127 
128         if (!NumberUtils.isNumber(propertyCycle)) {
129             poolConfig.setPropertyCycle(NumberUtils.stringToInt(propertyCycle));
130         }
131 
132         String acquireIncrement = (String) getAttribute(DatabaseConstant.C3P0_JDBC_ACQUIRE_INCREMENT);
133 
134         if (!NumberUtils.isNumber(acquireIncrement)) {
135             poolConfig.setAcquireIncrement(NumberUtils
136                     .stringToInt(acquireIncrement));
137         }
138 
139         // c3p0 version is below 0.8.5 , does't support acquireRetryAttempts,
140         // acquireRetryDelay, breakAfterAcquireFailure,
141         // usesTraditionalReflectiveProxies
142 
143         String forceIgnoreUnresolvedTransactions = (String) getAttribute(DatabaseConstant.C3P0_JDBC_FORCE_IGNORE_UNRESOLVED_TRANS);
144 
145         if (!StringUtils.isEmpty(forceIgnoreUnresolvedTransactions)) {
146             poolConfig.setForceIgnoreUnresolvedTransactions(BooleanUtils
147                     .toBoolean(forceIgnoreUnresolvedTransactions));
148         }
149 
150         String numHelperThreads = (String) getAttribute(DatabaseConstant.C3P0_JDBC_NUM_HELPER_THREADS);
151 
152         if (!NumberUtils.isNumber(numHelperThreads)) {
153             poolConfig.setNumHelperThreads(NumberUtils
154                     .stringToInt(numHelperThreads));
155         }
156 
157         String jdbcURL = (String) getAttribute(DatabaseConstant.JDBC_URL);
158         if (StringUtils.isEmpty(jdbcURL)) {
159             logger.error("No JDBC url was specified by database.properties");
160             throw new DataSourceConfigurationException(
161                     "No JDBC url was specified");
162         } else {
163             String jdbcUsername = (String) getAttribute(DatabaseConstant.JDBC_USERNAME);
164             String jdbcPassword = (String) getAttribute(DatabaseConstant.JDBC_PASSWORD);
165 
166             DataSource unpooledDataSource = DataSources.unpooledDataSource(
167                     jdbcURL, jdbcUsername, jdbcPassword);
168             dataSource = DataSources.pooledDataSource(unpooledDataSource,
169                     poolConfig);
170         }
171         return dataSource;
172     }
173 
174     /***
175      * Return the configuration attribute with the specified name (if any), or
176      * <code>null</code> if there is no such attribute.
177      * 
178      * @param name Name of the attribute to return
179      * @return attribute
180      */
181     public Object getAttribute(String name) {
182         return attributes.get(name);
183     }
184 
185     /***
186      * Return an array containing the names of all currently defined
187      * configuration attributes. If there are no such attributes, a zero length
188      * array is returned.
189      * 
190      * @return attribute names
191      */
192     public String[] getAttributeNames() {
193         Vector names = new Vector();
194         Enumeration keys = attributes.keys();
195         while (keys.hasMoreElements()) {
196             names.addElement(keys.nextElement());
197         }
198         String results[] = new String[names.size()];
199         for (int i = 0; i < results.length; i++) {
200             results[i] = (String) names.elementAt(i);
201         }
202         return (results);
203     }
204 
205     /***
206      * Set the configuration attribute with the specified name. Calling this
207      * with a <code>null</code> value is equivalent to calling
208      * <code>removeAttribute(name)</code>.
209      * 
210      * @param name Name of the attribute to set
211      * @param value Value of the attribute to set, or <code>null</code> to
212      *            remove any setting for this attribute
213      */
214     public void setAttribute(String name, Object value) {
215         if (value == null) {
216             attributes.remove(name);
217         } else {
218             attributes.put(name, value);
219         }
220     }
221 
222     /***
223      * Remove any configuration attribute associated with the specified name. If
224      * there is no such attribute, no action is taken.
225      * 
226      * @param name Name of the attribute to remove
227      */
228     public void removeAttribute(String name) {
229         attributes.remove(name);
230     }
231 
232 }