package org.maachang.dao.dbms.pool;

import java.util.HashMap;

/**
 * コネクションプールファクトリ.
 * 
 * @version 2007/10/18
 * @author masahito suzuki
 * @since MaachangDao 1.00
 */
public class ConnectPoolFactory {
    /**
     * コネクション管理.
     */
    private final HashMap<String, DbcpPooling> connectManager = new HashMap<String, DbcpPooling>();

    /**
     * シングルトン.
     */
    private static final ConnectPoolFactory SNGL = new ConnectPoolFactory();

    /**
     * 同期.
     */
    private final Object sync = new Object();

    /**
     * コンストラクタ.
     */
    private ConnectPoolFactory() {

    }

    /**
     * オブジェクトを取得.
     * @param ConnectPoolFactory
     *            オブジェクトが返されます.
     */
    public static final ConnectPoolFactory getInstance() {
        return SNGL;
    }

    /**
     * 全てのコネクションをクリア.
     */
    public void clear() {
        connectManager.clear();
    }
    
    /**
     * コネクションオブジェクト追加.
     * @param name 追加対象のコネクション名を設定します.
     * @param driver 対象のJDBCドライバ名を設定します.
     * @param url JDBC接続先URLを設定します.
     * @param user JDBC接続ユーザ名を設定します.
     * @param passwd JDBC接続パスワードを設定します.
     * @param keepAlive アイドル時の破棄時間を設定します.
     * @param max プーリング最大数を設定します.
     * @param checkSQL 接続確認用SQL文を設定します.
     * @param readOnly 接続オブジェクトを読み込み専用にするか設定します.
     * @param autoCommit オートコミットを行う場合は[true]を設定します.
     */
    public void add(String name,String driver,String url, String user, String passwd,long keepAlive,int max,
            String checkSQL,boolean readOnly,boolean autoCommit ) throws Exception {
        if (url == null || (url = url.trim()).length() <= 0) {
            throw new IllegalArgumentException("指定urlは不正です");
        }
        if (name == null || (name = name.trim()).length() <= 0) {
            throw new IllegalArgumentException("指定名は不正です");
        }
        synchronized (sync) {
            if (connectManager.get(name) != null) {
                throw new IllegalArgumentException("指定名[" + name + "]は既に存在します");
            }
            DbcpPooling obj = new DbcpPooling(driver,url,user,passwd,keepAlive,max,checkSQL,readOnly,autoCommit ) ;
            connectManager.put(name, obj);
        }
    }

    /**
     * 削除処理. <BR>
     * <BR>
     * 指定名の内容を削除します. <BR>
     * 
     * @param name
     *            削除対象の名前を設定します.
     */
    public void remove(String name) {
        if (name == null || (name = name.trim()).length() <= 0) {
            return;
        }
        synchronized (sync) {
            if (connectManager.get(name) != null) {
                connectManager.remove(name);
            }
        }
    }

    /**
     * コネクションオブジェクト生成して取得.
     * @param driver 対象のJDBCドライバ名を設定します.
     * @param url JDBC接続先URLを設定します.
     * @param user JDBC接続ユーザ名を設定します.
     * @param passwd JDBC接続パスワードを設定します.
     * @param keepAlive アイドル時の破棄時間を設定します.
     * @param max プーリング最大数を設定します.
     * @param checkSQL 接続確認用SQL文を設定します.
     * @param readOnly 接続オブジェクトを読み込み専用にするか設定します.
     * @param autoCommit オートコミットを行う場合は[true]を設定します.
     * @return ConnectManager 取得されたコネクションマネージャが返されます.
     * @exception IllegalArgumentException
     *                入力例外.
     */
    public static ConnectManager get(String driver,String url, String user, String passwd,long keepAlive,int max,
            String checkSQL,boolean readOnly,boolean autoCommit ) throws Exception {
        if (url == null || (url = url.trim()).length() <= 0) {
            throw new IllegalArgumentException("指定urlは不正です");
        }
        DbcpPooling obj = new DbcpPooling(driver,url,user,passwd,keepAlive,max,checkSQL,readOnly,autoCommit ) ;
        return new ConnectManager(obj);
    }

    /**
     * 情報取得. <BR>
     * <BR>
     * 情報を取得します. <BR>
     * 
     * @param name
     *            取得対象の名前を設定します.
     * @return ConnectManager 取得されたコネクションマネージャが返されます.
     */
    public ConnectManager get(String name) {
        if (name == null || (name = name.trim()).length() <= 0) {
            return null;
        }
        DbcpPooling man = null;
        synchronized (sync) {
            man = connectManager.get(name);
        }
        ConnectManager ret = null;
        if (man != null) {
            try {
                ret = new ConnectManager(man);
            } catch (Exception e) {
                ret = null;
            }
        }
        return ret;
    }

    /**
     * 登録名一覧を取得. <BR>
     * <BR>
     * 登録されているオブジェクト一覧を取得します. <BR>
     * 
     * @return String[] 登録されている内容一覧が返されます.
     */
    public String[] getNames() {
        String[] ret = null;
        Object[] objs = null;
        synchronized (sync) {
            int len = connectManager.size();
            if (len > 0) {
                objs = connectManager.keySet().toArray();
            }
        }
        if (objs != null) {
            int len = objs.length;
            ret = new String[len];
            for (int i = 0; i < len; i++) {
                ret[i] = (String) objs[i];
                objs[i] = null;
            }
            objs = null;
        }
        return ret;
    }

    /**
     * 登録数を取得. <BR>
     * <BR>
     * 登録されている数を取得します. <BR>
     * 
     * @return int 登録されている数が返されます.
     */
    public int size() {
        int ret = 0;
        synchronized (sync) {
            ret = connectManager.size();
        }
        return ret;
    }
}
