package org.maachang.session.client.net ;

import org.maachang.connector.ClientConnector;
import org.maachang.session.client.PSession;
import org.maachang.session.client.net.protocol.ClGetSessionKeyProtocol;
import org.maachang.session.client.net.protocol.ClPutSessionKeyProtocol;
import org.maachang.session.client.net.protocol.ClRemoveSessionKeyProtocol;
import org.maachang.session.client.net.protocol.ClUpdateSessionIdProtocol;
import org.maachang.session.client.net.protocol.IOClientProtocol;
import org.maachang.session.engine.PersistenceDefine;

/**
 * クライアント永続化セッションネットアクセス用.
 * 
 * @version 2008/05/25
 * @author masahito suzuki
 * @since PersistenceSession 1.00
 */
class PSessionNetImpl implements PSession {
    
    /**
     * クライアントコネクタ.
     */
    private ClientConnector conn = null ;
    
    /**
     * セッションId.
     */
    private String sessionId = null ;
    
    /**
     * 各プロトコルオブジェクト.
     */
    private final ClPutSessionKeyProtocol putPlt = new ClPutSessionKeyProtocol() ;
    private final ClRemoveSessionKeyProtocol removePlt = new ClRemoveSessionKeyProtocol() ;
    private final ClGetSessionKeyProtocol getPlt = new ClGetSessionKeyProtocol() ;
    private final ClUpdateSessionIdProtocol updatePlt = new ClUpdateSessionIdProtocol() ;
    
    /**
     * コンストラクタ.
     * @param conn クライアントコネクターを設定します.
     * @exception Exception 例外.
     */
    public PSessionNetImpl( String sessionId,ClientConnector conn ) throws Exception {
        if( sessionId == null || conn == null ) {
            throw new IllegalArgumentException( "引数は不正です" ) ;
        }
        this.conn = conn ;
        this.sessionId = sessionId ;
    }
    
    /**
     * デストラクタ.
     */
    protected void finalize() throws Exception {
        conn = null ;
        sessionId = null ;
    }
    
    /**
     * 指定要素を追加.
     * @param key 対象のKey名を設定します.
     * @param value 対象の要素を設定します.
     * @exception Exception 例外.
     */
    public void put( String key,Object value ) throws Exception {
        putPlt.clear() ;
        putPlt.create( sessionId,key,value ) ;
        try {
            IOClientProtocol.execution( conn,putPlt,PersistenceDefine.PROTOCOL_OFFSET ) ;
        } finally {
            putPlt.clear() ;
        }
    }
    
    /**
     * 指定要素を削除.
     * @param key 対象のKey名を設定します.
     * @exception Exception 例外.
     */
    public void remove( String key ) throws Exception {
        removePlt.clear() ;
        removePlt.create( sessionId,key ) ;
        try {
            IOClientProtocol.execution( conn,removePlt,PersistenceDefine.PROTOCOL_OFFSET ) ;
        } finally {
            removePlt.clear() ;
        }
    }
    
    /**
     * 指定要素を取得.
     * @param key 対象のKey名を設定します.
     * @return Object 対象の要素が返されます.
     * @exception Exception 例外.
     */
    public Object get( String key ) throws Exception {
        getPlt.clear() ;
        getPlt.create( sessionId,key ) ;
        Object ret = null ;
        try {
            IOClientProtocol.execution( conn,getPlt,PersistenceDefine.PROTOCOL_OFFSET ) ;
            ret = getPlt.getResult() ;
        } finally {
            getPlt.clear() ;
        }
        return ret ;
    }
    
    /**
     * セッションIDを取得.
     * @return String セッションIDが返されます.
     * @exception Exception 例外.
     */
    public String getSessionId() throws Exception {
        return sessionId ;
    }
    
    /**
     * 現在のセッション更新時間を取得.
     * @return long セッション更新時間が返されます.
     * @exception Exception 例外.
     */
    public long getUpdateTime() throws Exception {
        updatePlt.clear() ;
        updatePlt.create( sessionId ) ;
        long ret = -1L ;
        try {
            IOClientProtocol.execution( conn,updatePlt,PersistenceDefine.PROTOCOL_OFFSET ) ;
            Object v = updatePlt.getResult() ;
            if( v != null ) {
                ret = ( ( Long )v ).longValue() ;
            }
        } finally {
            updatePlt.clear() ;
        }
        return ret ;
    }
}

