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, OnePoolManager> connectManager = new HashMap<String, OnePoolManager>();

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

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

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

    }

    /**
     * シングルトン. <BR>
     * <BR>
     * このオブジェクトを取得します. <BR>
     * 
     * @param ConnectPoolFactory
     *            オブジェクトが返されます.
     */
    public static final ConnectPoolFactory getInstance() {
        return SNGL;
    }

    /**
     * 全てのコネクションをクリア. <BR>
     * <BR>
     * 全てのコネクションをクリアします.
     */
    public void clear() {
        connectManager.clear();
    }

    /**
     * コネクションオブジェクト追加. <BR>
     * <BR>
     * 条件を設定してコネクションオブジェクトを追加します. <BR>
     * 
     * @param name
     *            コネクションオブジェクト格納対象名を設定します.
     * @param url
     *            コネクションURLを設定します.
     * @param user
     *            コネクションユーザ名を設定します.
     * @param passwd
     *            コネクションパスワードを設定します.
     * @param max
     *            最大プーリングコネクション管理要素を設定します.
     * @param checkSQL
     *            コネクションチェックSQLを設定します.
     * @exception IllegalArgumentException
     *                入力例外.
     */
    public void add(String name, String url, String user, String passwd, int max)
            throws IllegalArgumentException {
        this.add(name, url, user, passwd, max, null);
    }

    /**
     * コネクションオブジェクト追加. <BR>
     * <BR>
     * 条件を設定してコネクションオブジェクトを追加します. <BR>
     * 
     * @param name
     *            コネクションオブジェクト格納対象名を設定します.
     * @param url
     *            コネクションURLを設定します.
     * @param user
     *            コネクションユーザ名を設定します.
     * @param passwd
     *            コネクションパスワードを設定します.
     * @param max
     *            最大プーリングコネクション管理要素を設定します.
     * @param checkSQL
     *            コネクションチェックSQLを設定します.
     * @exception IllegalArgumentException
     *                入力例外.
     */
    public void add(String name, String url, String user, String passwd,
            int max, String checkSQL) throws IllegalArgumentException {
        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 + "]は既に存在します");
            }
            OnePoolManager obj = new OnePoolManager(url, user, passwd, max,
                    checkSQL);
            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);
            }
        }
    }

    /**
     * コネクションオブジェクト生成して取得.<BR>
     * <BR>
     * 条件を設定してコネクションオブジェクトを生成して取得します. <BR>
     * 
     * @param url
     *            コネクションURLを設定します.
     * @param user
     *            コネクションユーザ名を設定します.
     * @param passwd
     *            コネクションパスワードを設定します.
     * @param max
     *            最大プーリングコネクション管理要素を設定します.
     * @param checkSQL
     *            コネクションチェックSQLを設定します.
     * @return ConnectManager 取得されたコネクションマネージャが返されます.
     * @exception IllegalArgumentException
     *                入力例外.
     */
    public static ConnectManager get(String url, String user, String passwd,
            int max, String checkSQL) throws IllegalArgumentException {
        if (url == null || (url = url.trim()).length() <= 0) {
            throw new IllegalArgumentException("指定urlは不正です");
        }
        OnePoolManager obj = new OnePoolManager(url, user, passwd, max,
                checkSQL);
        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;
        }
        OnePoolManager 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;
    }
}
