/**
* Copyright (c) 2004-2011 Wang Jinbao(Julian Wong), http://www.ralasafe.com
* Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package org.ralasafe.db;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ralasafe.RalasafeException;
import org.ralasafe.util.DBUtil;
import org.ralasafe.util.IOUtil;
import org.ralasafe.util.StringUtil;
public class DBPower {
private static Log log=LogFactory.getLog( DBPower.class );
private static final String DATASOURCES_CONFIG_FILE = "ralasafe/datasources.xml";
public static final String BASE_CONFIG_DIR_MAP_KEY = "baseConfigDir";
public static final String DATASOURCES_CONFIG_FILE_MAP_KEY = "datasourcesConfigFile";
private static final int DEFAULT_MAX_BATCH_SIZE = 50;
private static int maxBatchSize = DEFAULT_MAX_BATCH_SIZE;
// private static DataSourceProviderDbcpImpl defaultDs=null;
private static String defaultDsName = "ralasafe";
private static String defaultAppDsName;
/** key/value=datasourceName<String>/ds<DataSource> */
private static Map dsnameMap = new HashMap();
/** key/value=tableId<Integer>/DataSource */
private static Map tableIdDsMap = new HashMap();
/**
* key/value=datasourceName<String>/Map[key/value=tableName<String>/tableId<
* Integer>]
*/
private static Map dsTableNameMap = new HashMap();
private static int tableIdIndex = 1;
private static boolean started;
public static boolean isStarted() {
return started;
}
public static void on(Map map) {
if (started) {
return;
}
started = true;
if (map == null) {
map = new HashMap();
}
String configFile = (String) map.get(DATASOURCES_CONFIG_FILE_MAP_KEY);
String baseDir = (String) map.get(BASE_CONFIG_DIR_MAP_KEY);
if (baseDir == null) {
baseDir = "";
}
if (configFile == null) {
configFile = DATASOURCES_CONFIG_FILE;
}
configFile = baseDir + configFile;
String line = System.getProperty("line.separator");
System.out.println("**** Starting Ralasafe datasource ......");
System.out.println("\t\tDirectory: " + baseDir);
// startup datasource and regist into dsnameMap
DataSourceHelper helper = new DataSourceHelper(configFile);
List configs = helper.parseConfig();
int count = configs.size();
for (int i = 0; i < count; i++) {
DataSourceConfig config = (DataSourceConfig) configs.get(i);
Properties props = new Properties();
FileInputStream fis = null;
try {
fis = new FileInputStream(baseDir + config.getConfigFile());
props.load(fis);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtil.close(fis);
}
DataSource ds = null;
String implType = props.getProperty("type", "ralasafe");
if (implType.equalsIgnoreCase("ralasafe")) {
DataSourceProviderDbcpImpl impl = new DataSourceProviderDbcpImpl();
String validInfo = impl.getValidInfo(props);
StringBuffer buff = new StringBuffer();
buff.append(config.toString()).append(line);
if (validInfo == null) {
impl.setup(props);
impl.setName(config.getName());
ds = impl;
} else {
buff.append("Error: " + validInfo).append(line);
}
buff.append(impl).append(line);
System.out.println(buff.toString());
} else if (implType.equalsIgnoreCase("jndi")) {
DataSourceProviderJndiImpl impl = new DataSourceProviderJndiImpl();
String validInfo = impl.getValidInfo(props);
StringBuffer buff = new StringBuffer();
buff.append(config.toString()).append(line);
if (validInfo == null) {
impl.setup(props);
impl.setName(config.getName());
ds = impl;
} else {
buff.append("Error: " + validInfo).append(line);
}
buff.append(impl).append(line);
System.out.println(buff.toString());
} else if (implType.equalsIgnoreCase("method")) {
DataSourceProviderMethodImpl impl = new DataSourceProviderMethodImpl();
String validInfo = impl.getValidInfo(props);
StringBuffer buff = new StringBuffer();
buff.append(config.toString()).append(line);
if (validInfo == null) {
impl.setup(props);
impl.setName(config.getName());
ds = impl;
} else {
buff.append("Error: " + validInfo).append(line);
}
buff.append(impl).append(line);
System.out.println(buff.toString());
} else {
String msg="Can't setup data source! Unknown data source type:" + implType;
log.error( msg );
throw new RuntimeException( msg );
}
if (ds != null) {
ds.setShowAllSchemas(config.isShowAllSchemas());
ds.setSchemas(config.getSchemas());
dsnameMap.put(config.getName(), ds);
}
}
// find default app ds name (business ds name)
for (int i = 0; i < count; i++) {
DataSourceConfig config = (DataSourceConfig) configs.get(i);
String name = config.getName();
if (!name.equals("ralasafe")) {
defaultAppDsName = name;
break;
}
}
if (!dsnameMap.containsKey("ralasafe")) {
String str = "Error: no datasource with name=\"ralasafe\" found!";
System.out.println(str);
System.out.println("**** Ralasafe datasource failed!");
throw new RuntimeException();
}
System.out.println("**** Ralasafe datasource started successfully!");
}
public static int getTableId(String dsName, String tableName) {
if (StringUtil.isEmpty(dsName)) {
dsName = defaultDsName;
}
Map tableNameMap = (Map) dsTableNameMap.get(dsName);
if (tableNameMap == null) {
tableNameMap = new HashMap();
dsTableNameMap.put(dsName, tableNameMap);
}
Integer tableId = (Integer) tableNameMap.get(tableName);
if (tableId == null) {
tableId = new Integer(tableIdIndex);
tableIdIndex++;
tableNameMap.put(tableName, tableId);
DataSource ds = (DataSource) dsnameMap.get(dsName);
tableIdDsMap.put(tableId, ds);
}
return tableId.intValue();
}
/**
*
* @param entityName
* @return
* @throws SQLException
*/
public static Connection getConnection(int tableId) throws DBLevelException {
try {
DataSource ds = (DataSource) tableIdDsMap.get(new Integer(tableId));
if (ds == null) {
String msg = "No datasource found in table with tableId="
+ tableId + "";
throw new RalasafeException(msg);
// ds = (DataSource)dsnameMap.get( defaultDsName);
}
return ds.getDataSource().getConnection();
} catch (SQLException e) {
log.error( "", e );
throw new DBLevelException(e);
}
}
public static String getDatasourceName(int tableId) {
DataSource ds = (DataSource) tableIdDsMap.get(new Integer(tableId));
return ds.getName();
}
public static Connection[] getConnections(int[] tableIds)
throws DBLevelException {
Connection[] conns = new Connection[tableIds.length];
Map dsNameConnIndexMap = new HashMap();
try {
for (int i = 0; i < tableIds.length; i++) {
int tableId = tableIds[i];
DataSource ds = (DataSource) tableIdDsMap.get(new Integer(
tableId));
String name = ds.getName();
if (dsNameConnIndexMap.containsKey(name)) {
int previousIndex = ((Integer) dsNameConnIndexMap.get(name))
.intValue();
conns[i] = conns[previousIndex];
} else {
conns[i] = ds.getDataSource().getConnection();
dsNameConnIndexMap.put(name, new Integer(i));
}
}
} catch (SQLException e) {
dsNameConnIndexMap.clear();
for (int i = 0; i < conns.length; i++) {
Connection conn = conns[i];
DBUtil.close(conn);
}
throw new DBLevelException(e);
}
return conns;
}
public static Connection[] getUniqueConnections(int[] tableIds)
throws DBLevelException {
Connection[] conns = new Connection[tableIds.length];
try {
for (int i = 0; i < tableIds.length; i++) {
int tableId = tableIds[i];
DataSource ds = (DataSource) tableIdDsMap.get(new Integer(
tableId));
String name = ds.getName();
conns[i] = ds.getDataSource().getConnection();
}
} catch (SQLException e) {
for (int i = 0; i < conns.length; i++) {
Connection conn = conns[i];
DBUtil.close(conn);
}
throw new DBLevelException(e);
}
return conns;
}
public static void setMaxBatchSize(int maxBatchSize) {
DBPower.maxBatchSize = maxBatchSize;
}
public static int getMaxBatchSize() {
return maxBatchSize;
}
public static Connection getConnection(String dsName) {
if (dsName == null) {
dsName = defaultDsName;
}
DataSource ds = (DataSource) dsnameMap.get(dsName);
if (ds == null) {
String msg = "Can't get connection. Cause: datasource with name=" + dsName + " not found.";
log.error( msg );
throw new RalasafeException(msg);
}
try {
return ds.getDataSource().getConnection();
} catch (SQLException e) {
log.error( "", e );
throw new DBLevelException(e);
}
}
public static Collection getDsNames() {
return dsnameMap.keySet();
}
/**
* Return default application datasource name. If many application datasource exist, return the first one
* which it not named with 'ralasafe'.
* If no application datasource exist, return 'ralasafe'.
*
* @return
*/
public static String getDefaultAppDsName() {
return defaultAppDsName == null ? defaultDsName : defaultAppDsName;
}
public static String getDefaultDsName() {
return defaultDsName;
}
public static DataSource getDataSource(String dsName) {
return (DataSource) dsnameMap.get(dsName);
}
}