package org.maachang.session.engine ;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.maachang.conf.Config;
import org.maachang.conf.ReadConfigUtil;
import org.maachang.dbm.MDbm;
import org.maachang.dbm.MDbmIO;
import org.maachang.dbm.MDbmManager;

/**
 * 永続化サービス.
 * 
 * @version 2008/05/25
 * @author masahito suzuki
 * @since PersistenceSession 1.00
 */
public class PersistenceService {
    
    /**
     * ログ出力.
     */
    private static final Log LOG = LogFactory.getLog( PersistenceService.class ) ;
    
    /**
     * MDBMコンフィグファイル名.
     */
    private static final String MDBM_CONF = "./conf/mdbm.conf" ;
    
    /**
     * セッションコンフィグファイル名.
     */
    private static final String SESSION_CONF = "./conf/session.conf" ;
    
    /**
     * シングルトン.
     */
    private static final PersistenceService SNGL = new PersistenceService() ;
    
    /**
     * 永続化オブジェクト.
     */
    private PersistenceEngineImpl engine = null ;
    
    /**
     * コンストラクタ.
     */
    private PersistenceService() {
    }
    
    /**
     * オブジェクトを取得.
     * @return PersistenceService オブジェクトが返されます.
     */
    public static final PersistenceService getInstance() {
        return SNGL ;
    }
    
    /**
     * オブジェクトを生成.
     * @exception Exception 例外.
     */
    public synchronized void init() throws Exception {
        if( this.engine == null ) {
            Config conf = new Config() ;
            if( ReadConfigUtil.readConfig( conf,MDBM_CONF ) == false ||
                conf.isSection( "mdbm" ) == false ) {
                throw new IOException( "mdbm.confの読み込みに失敗しました" ) ;
            }
            MDbmManager.getInstance().open( conf.get( "mdbm","directory",0 ) ) ;
            conf = null ;
            MDbm mdbm = MDbmManager.getInstance().getMDbm() ;
            this.init( mdbm ) ;
        }
    }
    
    /**
     * オブジェクトを生成.
     * @param mdbm 対象のMDBMを設定します.
     * @exception Exception 例外.
     */
    public synchronized void init( MDbm mdbm ) throws Exception {
        if( this.engine == null ) {
            LOG.info( "## PersistenceService - 生成." ) ;
            if( mdbm == null || mdbm.isUse() == false ) {
                throw new IllegalArgumentException( "指定MDBMは不正です" ) ;
            }
            else if( ( mdbm instanceof MDbmIO ) == false ) {
                throw new IllegalArgumentException( "MDbmはRemote及びTransactionでは扱えません" ) ;
            }
            try {
                Config conf = new Config() ;
                if( ReadConfigUtil.readConfig( conf,SESSION_CONF ) == false ||
                    conf.isSection( "session" ) == false ) {
                    this.engine = new PersistenceEngineImpl(
                        MDbmManager.getInstance().getMDbmOp( mdbm ),
                        -1,-1 ) ;
                }
                else {
                    this.engine = new PersistenceEngineImpl(
                        MDbmManager.getInstance().getMDbmOp( mdbm ),
                        conf.getInt( "session","cacheTime",0 ),
                        conf.getInt( "session","sessionTime",0 ) ) ;
                }
            } catch( Exception e ) {
                this.engine = null ;
                throw e ;
            }
        }
    }
    
    /**
     * オブジェクトを破棄.
     */
    public synchronized void destroy() {
        if( this.engine != null ) {
            LOG.info( "## PersistenceService - 破棄." ) ;
            try {
                this.engine.destroy() ;
            } catch( Exception e ) {
            }
        }
        this.engine = null ;
    }
    
    /**
     * PersistenceEngineオブジェクトを取得.
     * @return PersistenceEngine PersistenceEngineオブジェクトが返されます.
     */
    public synchronized PersistenceEngine getEngine() {
        return this.engine ;
    }
}
