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