package jef.database.datasource;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.DataSource;
import jef.common.log.LogUtil;
import jef.database.DbUtils;
import jef.database.dialect.DatabaseDialect;
import jef.database.dialect.AbstractDialect;
import jef.tools.StringUtils;
/**
* DataSource工具类
*
* @author jiyi
*
*/
public class DataSources {
private static String[] DataSourceClz = { "org.logicalcobwebs.proxool.ProxoolDataSource", "com.mchange.v2.c3p0.ComboPooledDataSource", "org.apache.commons.dbcp.BasicDataSource", "org.springframework.jdbc.datasource.AbstractDriverBasedDataSource",
"com.alibaba.druid.pool.DruidAbstractDataSource", "com.jolbox.bonecp.BoneCPDataSource", "org.apache.tomcat.jdbc.pool.DataSource" };
private static String[] adapterClz = { "jef.database.datasource.ProxoolDataSourceWrapper", "jef.database.datasource.C3p0DataSourceWrapper", "jef.database.datasource.DbcpDataSourceWrapper", "jef.database.datasource.DriverManagerDataSourceWrapper",
"jef.database.datasource.DruidDataSourceWrapper", "jef.database.datasource.BoneCpWrapper", "jef.database.datasource.TomcatCpWrapper" };
private DataSources() {
}
/**
* 将给出的DataSource包装为DataSourceWrapper对象
* DataSourceWrapper对象能够提供各种DataSource配置信息的获取和修改 这个功能目前能识别Spring,Apache
* DBCP,c3p0,Druid, Proxool等若干框架的DataSource
*
* @param datasource
* @return 如果无法包装将返回null
* @see DataSourceWrapper
* @see DataSourceInfo
*/
public static DataSourceWrapper wrapFor(DataSource datasource) {
Class<? extends DataSource> iface = datasource.getClass();
if (datasource instanceof DataSourceWrapper) {
return (DataSourceWrapper) datasource;
}
for (int index=0;index<DataSourceClz.length;index++) {
try {
String s=DataSourceClz[index];
if (isAssiableFrom(iface, s)) {
Class<?> c = Class.forName(adapterClz[index]);
DataSourceWrapper wrapper = (DataSourceWrapper) c.newInstance();
wrapper.setWrappedDataSource(datasource);
return wrapper;
}
} catch (NoClassDefFoundError e) {
// 不用任何输出
} catch (ClassNotFoundException e) {
// 不用任何输出
} catch (Exception e) {
LogUtil.exception(e);
}
}
if (System.getProperty("no.refelcting.datasource.wrapper") == null) {
try {
RefectingHackDataSourceWrapper w = new RefectingHackDataSourceWrapper(datasource);
LogUtil.warn(StringUtils.concat("Unknown datasource type:", datasource.getClass().getName(), " Using refelcting datasource wrapper to access it. "));
return w;
} catch (Exception e) {
LogUtil.warn("wrap as RefectingHackDataSourceWrapper error:{}",e.getMessage());
}
}
return null;
}
private static boolean isAssiableFrom(Class<? extends DataSource> iface, String s) {
Class<?> clz=iface;
while(clz!=Object.class && clz!=null){
if(s.equals(clz.getName())){
return true;
}
clz=clz.getSuperclass();
}
return false;
}
public static DataSource getAsDataSource(DataSourceInfo dsi) {
if (dsi != null) {
if (dsi instanceof DataSource) {
return (DataSource) dsi;
} else {
return new SimpleDataSource(dsi);
}
}
return null;
}
public static boolean isPool(DataSource ds) {
if (ds instanceof ConnectionPoolDataSource) {// 如果是JDK标准的连接池直接返回true
return true;
}
DataSourceWrapper dsw = DataSources.wrapFor(ds);
if (dsw == null) {// 無法包裝就認為不是池
return false;
}
return dsw.isConnectionPool();
}
/**
* 按给出的数据创建DataSource
*
* @param dbType
* @param host
* @param port
* @param database
* @param user
* @param password
* @return
*/
public static DataSource create(String dbType, String host, int port, String database, String user, String password) {
DatabaseDialect profile = AbstractDialect.getProfile(dbType);
if (profile == null) {
throw new UnsupportedOperationException("The database {" + dbType + "} was not supported yet..");
}
String url = profile.generateUrl(host, port, database);
return DbUtils.createSimpleDataSource(url, user, password);
}
}