package org.itscool.commons.connection;

import java.sql.Connection;
import java.sql.SQLException;

import javax.naming.InitialContext;
import javax.sql.DataSource;

/**
 * DataSourceからTransactionインスタンスを生成する為のクラスです
 */
public class DataSourceConnectionManager implements ConnectionManager{
    private static DataSourceConnectionManager instance = null;
    private String dsName;
    private DataSource ds;
    private boolean mode = false;        // AutoCommitモード
    private boolean showSql = false;		//SQL表示フラグ
    private boolean initFlg = false;
    
    public String toString(){
        StringBuffer sb = new StringBuffer();
        sb.append("DataSource Name:").append(dsName);
        sb.append(", ");
        sb.append("mode:").append(mode);
        sb.append(", ");
        sb.append("showSql:").append(showSql);
        return sb.toString();
    }
    
    /**
     * 唯一のConnectionManagerインスタンスを取得します
     *
     * @return 唯一のConnectionMangerインスタンスを返します
     */
    public static DataSourceConnectionManager getInstance() {
        if (instance == null) {
            instance = new DataSourceConnectionManager();
        }
        return instance;
    }
    
    public boolean isInit(){
        return initFlg;
    }
    
    /**
     * 初期化処理
     */
    public void init() {
        try {
            // 初期コンテキストを取得
            InitialContext ic = new InitialContext();
            // ルックアップしてデータソースを取得
            ds = (DataSource) ic.lookup(dsName);
            initFlg = true;
        } catch (Exception e) {
            throw new TransactionException(e);
        }
    }
    
    /**
     * Transactionインスタンスをプールから取得します
     * プールにTransactionインスタンスがない場合はnullを返します
     *
     * @return Transactionインスタンスを返します
     */
    public Transaction getTransaction() {
        Transaction trn = null;
        try {
            Connection con = ds.getConnection();
//add 2006/12/19 kano start プロクシに寄るResultSet、PrepardStatementの自動クローズ処理追加対応
            con = ProxyConnection.createProxy(con);
//add 2006/12/19 kano end プロクシに寄るResultSet、PrepardStatementの自動クローズ処理追加対応
            con.setAutoCommit(mode);
            trn = new Transaction(con);
            trn.setShowSql(showSql);
            
        } catch (SQLException se) {
            throw new TransactionException(se);
        }
        return trn;
    }
    
    /**
     * 不要になったConnectionインスタンスをプールに返します
     *
     * @param trn 不要になったTransactionインスタンス
     */
    public void returnTransaction(Transaction trn) {
        trn.close();
        trn = null;
    }
    
    /**
     * コネクションプールを開放し、終了します。
     */
    public void destroy() {
        
    }
    
    /**
     * データソース名を取得します
     * @return データソース名
     */
    public String getDsName() {
        return dsName;
    }
    
    /**
     * データソース名をセットします
     * @param dsName データソース名
     */
    public void setDsName(String dsName) {
        this.dsName = dsName;
    }
    
    /**
     * SQL表示モードを取得します
     * @return SQL表示の場合はtrueを返します
     */
    public boolean getShowSql() {
        return showSql;
    }
    /**
     * SQL表示モードをセットします
     * @param showSql SQL表示モード
     */
    public void setShowSql(boolean showSql) {
        this.showSql = showSql;
    }
    /**
     * AutoCommitモードをセットします
     * @param mode AutoCommitモード
     */
    public void setMode(boolean mode) {
        this.mode = mode;
    }
    /**
     * AutoCommitModeを取得します
     * @return AutoCommitModeが有効になっている場合はtureを返します
     */
    public boolean getMode() {
        return mode;
    }
}
