/*
* Copyright 2012 The Solmix Project
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.gnu.org/licenses/
* or see the FSF site: http://www.fsf.org.
*/
package org.solmix.sql;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.commons.dbcp.PoolableConnection;
import org.apache.commons.pool.ObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.solmix.api.exception.SlxException;
import org.solmix.api.pool.IPoolableObjectFactory;
import org.solmix.api.pool.SlxPoolableObjectFactory;
import org.solmix.commons.collections.DataTypeMap;
import org.solmix.runtime.SystemContext;
import org.solmix.runtime.cm.ConfigureUnit;
import org.solmix.runtime.cm.ConfigureUnitManager;
/**
*
* @author solmix
* @version 111039 0.1.1,1039
* @since 0.0.1
*
*
*/
public class PoolableSQLConnectionFactory extends
SlxPoolableObjectFactory<Connection>
{
private static Logger log = LoggerFactory.getLogger(PoolableSQLConnectionFactory.class.getName());
private final ConnectionManagerImpl connectionManager;
private String serverName;
private DataTypeMap sqlConfig;
private String pingTest;
private final SystemContext sc;
PoolableSQLConnectionFactory(String serverName, final SystemContext sc,
ConnectionManagerImpl connectionManager) throws SlxException
{
this(connectionManager, sc);
DataTypeMap serconfig = getConfig().getSubtree(serverName);
this.serverName = serverName;
init(serverName, serconfig);
}
/**
* @param serverName
* @param subtree
*/
private void init(String serverName, DataTypeMap sqlConfig) {
this.serverName = serverName;
this.sqlConfig = sqlConfig;
if (!sqlConfig.getBoolean("autoDeriveConfig", false)) {
pingTest = sqlConfig.getString("pingTest");
}
}
/**
* @param sc
*/
public PoolableSQLConnectionFactory(
final ConnectionManagerImpl connectionManager, final SystemContext sc)
{
this.connectionManager = connectionManager;
this.sc = sc;
}
protected DataTypeMap getConfig() {
ConfigureUnitManager cum = sc.getExtension(ConfigureUnitManager.class);
ConfigureUnit cu = null;
try {
cu = cum.getConfigureUnit(SQLDataSource.SERVICE_PID);
} catch (IOException e) {
// ignore
}
if (cu != null)
return cu.getProperties();
else
return new DataTypeMap();
}
/**
* {@inheritDoc}
*
* @see org.solmix.api.pool.SlxPoolableObjectFactory#makeUnpooledObject()
*/
@Override
public Connection makeUnpooledObject() throws Exception {
return connectionManager.getInternalConn(serverName, sqlConfig);
}
/**
* {@inheritDoc}
*
* @see org.apache.commons.pool.PoolableObjectFactory#activateObject(java.lang.Object)
*/
@Override
public void activateObject(Connection obj) throws Exception {
numActivateObjectCalls++;
}
/**
* {@inheritDoc}
*
* @see org.apache.commons.pool.PoolableObjectFactory#destroyObject(java.lang.Object)
*/
@Override
public void destroyObject(Connection arg0) throws Exception {
numDestroyObjectCalls++;
}
/**
* {@inheritDoc}
*
* @see org.apache.commons.pool.PoolableObjectFactory#makeObject()
*/
@Override
public Connection makeObject() throws Exception {
numMakeObjectCalls++;
Connection conn = makeUnpooledObject();
if (pool == null) {
log.debug("Returning unpooled Connection");
return conn;
} else {
log.debug("Returning pooled Connection");
return new PoolableConnection(conn, (ObjectPool) pool);
}
}
/**
* {@inheritDoc}
*
* @see org.apache.commons.pool.PoolableObjectFactory#passivateObject(java.lang.Object)
*/
@Override
public void passivateObject(Connection arg0) throws Exception {
numPassivateObjectCalls++;
}
/**
* {@inheritDoc}
*
* @see org.apache.commons.pool.PoolableObjectFactory#validateObject(java.lang.Object)
*/
@Override
public boolean validateObject(Connection obj) {
Connection conn = obj;
/**
* This method generally cannot be called to determine whether a
* connection to a database is valid or invalid. A typical client can
* determine that a connection is invalid by catching any exceptions
* that might be thrown when an operation is attempted.
*/
/*
* boolean isClosed = false; try { isClosed = conn.isClosed(); } catch
* (SQLException e1) { e1.printStackTrace(); } if (isClosed) return
* false;
*/
try {
if (pingTest != null) {
Statement s = conn.createStatement();
s.execute(pingTest);
}
return true;
} catch (SQLException e) {
try {
conn.close();
} catch (Exception ignored) {
}
}
return false;
}
/**
* {@inheritDoc}
*
* @see org.solmix.api.pool.IPoolableObjectFactory#newInstance(java.lang.Object)
*/
@Override
public IPoolableObjectFactory newInstance(Object key) throws SlxException {
return new PoolableSQLConnectionFactory(key.toString(), sc,
connectionManager);
}
}