001
014
015 package com.liferay.portal.dao.jdbc;
016
017 import com.liferay.portal.kernel.dao.jdbc.DataSourceFactory;
018 import com.liferay.portal.kernel.jndi.JNDIUtil;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.PropertiesUtil;
022 import com.liferay.portal.kernel.util.SortedProperties;
023 import com.liferay.portal.kernel.util.Validator;
024 import com.liferay.portal.util.PropsUtil;
025 import com.liferay.portal.util.PropsValues;
026 import com.liferay.util.PwdGenerator;
027
028 import com.mchange.v2.c3p0.ComboPooledDataSource;
029
030 import java.lang.management.ManagementFactory;
031
032 import java.util.Enumeration;
033 import java.util.Map;
034 import java.util.Properties;
035
036 import javax.management.MBeanServer;
037 import javax.management.ObjectName;
038
039 import javax.naming.InitialContext;
040
041 import javax.sql.DataSource;
042
043 import jodd.bean.BeanUtil;
044
045 import org.apache.commons.dbcp.BasicDataSourceFactory;
046 import org.apache.tomcat.jdbc.pool.PoolProperties;
047 import org.apache.tomcat.jdbc.pool.jmx.ConnectionPool;
048
049 import uk.org.primrose.pool.datasource.GenericDataSourceFactory;
050
051
055 public class DataSourceFactoryImpl implements DataSourceFactory {
056
057 public void destroyDataSource(DataSource dataSource) throws Exception {
058 if (dataSource instanceof ComboPooledDataSource) {
059 ComboPooledDataSource comboPooledDataSource =
060 (ComboPooledDataSource)dataSource;
061
062 comboPooledDataSource.close();
063 }
064 else if (dataSource instanceof org.apache.tomcat.jdbc.pool.DataSource) {
065 org.apache.tomcat.jdbc.pool.DataSource tomcatDataSource =
066 (org.apache.tomcat.jdbc.pool.DataSource)dataSource;
067
068 tomcatDataSource.close();
069 }
070 }
071
072 public DataSource initDataSource(Properties properties) throws Exception {
073 Properties defaultProperties = PropsUtil.getProperties(
074 "jdbc.default.", true);
075
076 PropertiesUtil.merge(defaultProperties, properties);
077
078 properties = defaultProperties;
079
080 String jndiName = properties.getProperty("jndi.name");
081
082 if (Validator.isNotNull(jndiName)) {
083 try {
084 return (DataSource)JNDIUtil.lookup(
085 new InitialContext(), jndiName);
086 }
087 catch (Exception e) {
088 _log.error("Unable to lookup " + jndiName, e);
089 }
090 }
091
092 DataSource dataSource = null;
093
094 String liferayPoolProvider =
095 PropsValues.JDBC_DEFAULT_LIFERAY_POOL_PROVIDER;
096
097 if (liferayPoolProvider.equalsIgnoreCase("c3p0") ||
098 liferayPoolProvider.equalsIgnoreCase("c3po")) {
099
100 if (_log.isDebugEnabled()) {
101 _log.debug("Initializing C3P0 data source");
102 }
103
104 dataSource = initDataSourceC3PO(properties);
105 }
106 else if (liferayPoolProvider.equalsIgnoreCase("dbcp")) {
107 if (_log.isDebugEnabled()) {
108 _log.debug("Initializing DBCP data source");
109 }
110
111 dataSource = initDataSourceDBCP(properties);
112 }
113 else if (liferayPoolProvider.equalsIgnoreCase("primrose")) {
114 if (_log.isDebugEnabled()) {
115 _log.debug("Initializing Primrose data source");
116 }
117
118 dataSource = initDataSourcePrimrose(properties);
119 }
120 else {
121 if (_log.isDebugEnabled()) {
122 _log.debug("Initializing Tomcat data source");
123 }
124
125 dataSource = initDataSourceTomcat(properties);
126 }
127
128 if (_log.isDebugEnabled()) {
129 _log.debug(
130 "Created data source " + dataSource.getClass().getName());
131
132 SortedProperties sortedProperties = new SortedProperties(
133 properties);
134
135 sortedProperties.list(System.out);
136 }
137
138 return dataSource;
139 }
140
141 public DataSource initDataSource(
142 String driverClassName, String url, String userName,
143 String password)
144 throws Exception {
145
146 Properties properties = new Properties();
147
148 properties.setProperty("driverClassName", driverClassName);
149 properties.setProperty("url", url);
150 properties.setProperty("username", userName);
151 properties.setProperty("password", password);
152
153 return initDataSource(properties);
154 }
155
156 protected DataSource initDataSourceC3PO(Properties properties)
157 throws Exception {
158
159 ComboPooledDataSource comboPooledDataSource =
160 new ComboPooledDataSource();
161
162 String identityToken = PwdGenerator.getPassword(PwdGenerator.KEY2, 8);
163
164 comboPooledDataSource.setIdentityToken(identityToken);
165
166 Enumeration<String> enu =
167 (Enumeration<String>)properties.propertyNames();
168
169 while (enu.hasMoreElements()) {
170 String key = enu.nextElement();
171 String value = properties.getProperty(key);
172
173
174
175 if (key.equalsIgnoreCase("driverClassName")) {
176 key = "driverClass";
177 }
178 else if (key.equalsIgnoreCase("url")) {
179 key = "jdbcUrl";
180 }
181 else if (key.equalsIgnoreCase("username")) {
182 key = "user";
183 }
184
185
186
187 if (isPropertyLiferay(key)) {
188 continue;
189 }
190
191
192
193 if (isPropertyDBCP(key)) {
194 continue;
195 }
196
197
198
199 if (isPropertyPrimrose(key)) {
200 continue;
201 }
202
203
204
205 if (isPropertyTomcat(key)) {
206 continue;
207 }
208
209 try {
210 BeanUtil.setProperty(comboPooledDataSource, key, value);
211 }
212 catch (Exception e) {
213 if (_log.isWarnEnabled()) {
214 _log.warn(
215 "Property " + key + " is not a valid C3PO property");
216 }
217 }
218 }
219
220 return comboPooledDataSource;
221 }
222
223 protected DataSource initDataSourceDBCP(Properties properties)
224 throws Exception {
225
226 return BasicDataSourceFactory.createDataSource(properties);
227 }
228
229 protected DataSource initDataSourcePrimrose(Properties properties)
230 throws Exception {
231
232 String poolName = PwdGenerator.getPassword(PwdGenerator.KEY2, 8);
233
234 properties.setProperty("poolName", poolName);
235
236 Enumeration<String> enu =
237 (Enumeration<String>)properties.propertyNames();
238
239 while (enu.hasMoreElements()) {
240 String key = enu.nextElement();
241
242 String value = properties.getProperty(key);
243
244
245
246 if (key.equalsIgnoreCase("driverClassName")) {
247 key = "driverClass";
248 }
249 else if (key.equalsIgnoreCase("url")) {
250 key = "driverURL";
251 }
252 else if (key.equalsIgnoreCase("username")) {
253 key = "user";
254 }
255
256 properties.setProperty(key, value);
257 }
258
259 GenericDataSourceFactory genericDataSourceFactory =
260 new GenericDataSourceFactory();
261
262 return genericDataSourceFactory.loadPool(poolName, properties);
263 }
264
265 protected DataSource initDataSourceTomcat(Properties properties)
266 throws Exception {
267
268 PoolProperties poolProperties = new PoolProperties();
269
270 for (Map.Entry<Object, Object> entry : properties.entrySet()) {
271 String key = (String)entry.getKey();
272 String value = (String)entry.getValue();
273
274
275
276 if (isPropertyLiferay(key)) {
277 continue;
278 }
279
280
281
282 if (isPropertyC3PO(key)) {
283 continue;
284 }
285
286
287
288 if (isPropertyPrimrose(key)) {
289 continue;
290 }
291
292 try {
293 BeanUtil.setProperty(poolProperties, key, value);
294 }
295 catch (Exception e) {
296 if (_log.isWarnEnabled()) {
297 _log.warn(
298 "Property " + key + " is not a valid Tomcat JDBC " +
299 "Connection Pool property");
300 }
301 }
302 }
303
304 String poolName = PwdGenerator.getPassword(PwdGenerator.KEY2, 8);
305
306 poolProperties.setName(poolName);
307
308 org.apache.tomcat.jdbc.pool.DataSource dataSource =
309 new org.apache.tomcat.jdbc.pool.DataSource(poolProperties);
310
311 if (poolProperties.isJmxEnabled()) {
312 org.apache.tomcat.jdbc.pool.ConnectionPool jdbcConnectionPool =
313 dataSource.createPool();
314
315 ConnectionPool jmxConnectionPool = jdbcConnectionPool.getJmxPool();
316
317 MBeanServer mBeanServer =
318 ManagementFactory.getPlatformMBeanServer();
319
320 ObjectName objectName = new ObjectName(
321 _TOMCAT_JDBC_POOL_OBJECT_NAME_PREFIX + poolName);
322
323 mBeanServer.registerMBean(jmxConnectionPool, objectName);
324 }
325
326 return dataSource;
327 }
328
329 protected boolean isPropertyC3PO(String key) {
330 if (key.equalsIgnoreCase("acquireIncrement") ||
331 key.equalsIgnoreCase("acquireRetryAttempts") ||
332 key.equalsIgnoreCase("acquireRetryDelay") ||
333 key.equalsIgnoreCase("connectionCustomizerClassName") ||
334 key.equalsIgnoreCase("idleConnectionTestPeriod") ||
335 key.equalsIgnoreCase("maxIdleTime") ||
336 key.equalsIgnoreCase("maxPoolSize") ||
337 key.equalsIgnoreCase("minPoolSize") ||
338 key.equalsIgnoreCase("numHelperThreads") ||
339 key.equalsIgnoreCase("preferredTestQuery")) {
340
341 return true;
342 }
343 else {
344 return false;
345 }
346 }
347
348 protected boolean isPropertyDBCP(String key) {
349 if (key.equalsIgnoreCase("defaultTransactionIsolation") ||
350 key.equalsIgnoreCase("maxActive") ||
351 key.equalsIgnoreCase("minIdle") ||
352 key.equalsIgnoreCase("removeAbandonedTimeout")) {
353
354 return true;
355 }
356 else {
357 return false;
358 }
359 }
360
361 protected boolean isPropertyLiferay(String key) {
362 if (key.equalsIgnoreCase("jndi.name") ||
363 key.equalsIgnoreCase("liferay.pool.provider")) {
364
365 return true;
366 }
367 else {
368 return false;
369 }
370 }
371
372 protected boolean isPropertyPrimrose(String key) {
373 if (key.equalsIgnoreCase("base") ||
374 key.equalsIgnoreCase("connectionTransactionIsolation") ||
375 key.equalsIgnoreCase("idleTime") ||
376 key.equalsIgnoreCase("numberOfConnectionsToInitializeWith")) {
377
378 return true;
379 }
380 else {
381 return false;
382 }
383 }
384
385 protected boolean isPropertyTomcat(String key) {
386 if (key.equalsIgnoreCase("fairQueue") ||
387 key.equalsIgnoreCase("jdbcInterceptors") ||
388 key.equalsIgnoreCase("jmxEnabled") ||
389 key.equalsIgnoreCase("timeBetweenEvictionRunsMillis") ||
390 key.equalsIgnoreCase("useEquals")) {
391
392 return true;
393 }
394 else {
395 return false;
396 }
397 }
398
399 private static final String _TOMCAT_JDBC_POOL_OBJECT_NAME_PREFIX =
400 "TomcatJDBCPool:type=ConnectionPool,name=";
401
402 private static Log _log = LogFactoryUtil.getLog(
403 DataSourceFactoryImpl.class);
404
405 }