package org.maachang.dao.dbms;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.maachang.conf.Config;
import org.maachang.conf.ReadIni;
import org.maachang.dao.dbms.kind.KindManager;
import org.maachang.dao.dbms.kind.SupportKind;

/**
 * DB情報を取得.
 * 
 * @version 2007/10/18
 * @author masahito suzuki
 * @since MaachangDao 1.00
 */
public class DbmsInfo {
    
    /**
     * デフォルト最大コネクション数.
     */
    private static final int DEF_MAX = 15 ;
    
    /**
     * デフォルトキープアライブ値.
     */
    private static final long DEF_KEEP_ALIVE = 120 * 1000L ;
    
    /**
     * セクション名.
     */
    private static final String DBMS_SECTION = "dbms" ;
    
    /**
     * レコードファクトリを取得.
     * <BR><BR>
     * 指定条件からレコードファクトリを取得します.
     * <BR>
     * @param conf 対象のコンフィグ情報を設定します.
     * @return RecordFactory 対象のレコードファクトリが返されます.
     * @exception Exception 例外.
     */
    public static final RecordFactory getRecordFactory( Config conf )
        throws Exception {
        // ＤＢアクセス.
        String adapter = conf.get(DBMS_SECTION,"adapter",0);
        String driver = conf.get(DBMS_SECTION,"driver",0);
        String url = conf.get(DBMS_SECTION,"url",0);
        String user = conf.get(DBMS_SECTION,"user",0);
        String passwd = conf.get(DBMS_SECTION,"passwd",0);
        String keepAlive = conf.get(DBMS_SECTION,"keepAlive",0);
        String max = conf.get(DBMS_SECTION,"max",0);
        String checkSQL = conf.get(DBMS_SECTION,"checksql",0);
        String readOnly = conf.get(DBMS_SECTION,"readOnly",0);
        String autoCommit = conf.get(DBMS_SECTION,"autoCommit",0);
        String debug = conf.get(DBMS_SECTION,"debug",0);
        
        int maxInt;
        try {
            maxInt = Integer.parseInt(max);
        } catch (Exception e) {
            maxInt = DEF_MAX;
        }
        if (maxInt <= 0) {
            maxInt = DEF_MAX;
        }
        long keepAliveTime ;
        try {
            keepAliveTime = Long.parseLong(keepAlive);
        } catch (Exception e) {
            keepAliveTime = DEF_KEEP_ALIVE;
        }
        if (keepAliveTime <= 0L) {
            keepAliveTime = DEF_KEEP_ALIVE;
        }
        boolean autoCommitFlag = false ;
        try {
            autoCommit = autoCommit.trim().toLowerCase() ;
            autoCommitFlag = ( autoCommit.equals( "true" ) || autoCommit.equals( "on" ) ) ;
        } catch( Exception e ) {
            autoCommitFlag = false ;
        }
        boolean readOnlyFlag = false ;
        try {
            readOnly = readOnly.trim().toLowerCase() ;
            readOnlyFlag = ( readOnly.equals( "true" ) || readOnly.equals( "on" ) ) ;
        } catch( Exception e ) {
            readOnlyFlag = false ;
        }
        boolean debugFlag = false ;
        try {
            debug = debug.trim().toLowerCase() ;
            debugFlag = debug.equals( "true" ) ;
        } catch( Exception e ) {
            debugFlag = false ;
        }
        return getRecordFactory( debugFlag, adapter, driver, url, user,
            passwd, keepAliveTime,maxInt, checkSQL, readOnlyFlag, autoCommitFlag ) ;
    }
    
    /**
     * レコードファクトリを生成.
     * <BR><BR>
     * 指定条件から、レコードファクトリ情報を生成します.
     * <BR>
     * @param debug 対象のデバッグモードを設定します.
     * @param adapter 対象のアダプタ名を設定します.
     * @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 RecordFactory 対象のレコードファクトリが返されます.
     * @exception Exception 例外.
     */
    public static final RecordFactory getRecordFactory(
        boolean debug,String adapter,String driver,String url, String user, String passwd,long keepAlive,int max,
        String checkSQL,boolean readOnly,boolean autoCommit ) throws Exception {
        SupportKind kind = KindManager.get( adapter ) ;
        if( kind == null ) {
            throw new IllegalArgumentException("非サポートのアダプタ名("+ adapter +
                ")が設定されています");
        }
        RecordFactory ret = new RecordFactory();
        ret.create(kind,debug,driver,url,user,passwd,keepAlive,max,checkSQL,readOnly,autoCommit);
        return ret ;
    }
    
    /**
     * 指定されたコンフィグファイルを取得.
     * <BR><BR>
     * 指定されたコンフィグファイルを取得します.
     * <BR>
     * @param name 対象のコンフィグファイル名を設定します.
     * @return Config 対象のコンフィグファイルが返されます.
     * @exception Exception 例外.
     */
    public static final Config getConfig( String name )
        throws Exception {
        return getConfig( new FileInputStream( name ) ) ;
    }
    
    /**
     * 指定されたコンフィグファイルを取得.
     * <BR><BR>
     * 指定されたコンフィグファイルを取得します.
     * <BR>
     * @param in 対象のInputStreamを設定します.
     * @return Config 対象のコンフィグファイルが返されます.
     * @exception Exception 例外.
     */
    public static final Config getConfig( InputStream in )
        throws Exception {
        BufferedReader buf = null ;
        try {
            Config ret = new Config() ;
            buf = new BufferedReader( new InputStreamReader( in,"UTF8" ) ) ;
            ReadIni.analisys( ret,buf ) ;
            buf.close() ;
            buf = null ;
            return ret ;
        } finally {
            if( buf != null ) {
                try {
                    buf.close() ;
                } catch( Exception e ) {
                }
            }
            buf = null ;
        }
    }
}

