package org.maachang.comet.httpd.engine.script.scripts;

import java.util.HashMap;
import java.util.Map;

import org.maachang.comet.httpd.HttpdErrorDef;
import org.maachang.comet.httpd.HttpdStateException;
import org.maachang.comet.httpd.engine.script.Script;
import org.maachang.comet.httpd.engine.script.ScriptDef;

/**
 * Application用スクリプトファクトリ.
 * 
 * @version 2007/08/24
 * @author masahito suzuki
 * @since MaachangComet 1.00
 */
public class ApplicationScriptFactory {
    
    /**
     * カレントディレクトリ.
     */
    private String currentDirectory = null ;
    
    /**
     * アプリケーションスクリプト格納用.
     */
    private Map<String,Script> applications = null ;
    
    /**
     * アプリケーションスクリプト生成用同期.
     */
    private final Object sync = new Object() ;
    
    /**
     * コンストラクタ.
     */
    private ApplicationScriptFactory() {
        
    }
    
    /**
     * コンストラクタ.
     * <BR><BR>
     * 条件を指定してオブジェクトを生成します.
     * <BR>
     * @param directory 対象のカレントディレクトリを設定します.
     * @exception Exception 例外.
     */
    public ApplicationScriptFactory( String currentDirectory )
        throws Exception {
        currentDirectory = ScriptDef.trimCurrentDirectory( currentDirectory ) ;
        this.currentDirectory = currentDirectory ;
        this.applications = new HashMap<String,Script>() ;
    }
    
    /**
     * アプリケーションスクリプトを取得.
     * <BR><BR>
     * アプリケーションスクリプトを取得します.
     * <BR>
     * @param name 対象のアプリケーションスクリプト名を設定します.
     * @return Script アプリケーションスクリプトが返されます.
     * @exception Exception 例外.
     */
    public Script getApplication( String name )
        throws Exception {
        if( name == null || ( name = name.trim() ).length() <= 0 ) {
            throw new HttpdStateException( HttpdErrorDef.HTTP11_500,
                "対象アプリケーション名は不正です" ) ;
        }
        String key = ScriptManager.cutScriptPlus( name ) ;
        Script ret = null ;
        synchronized( sync ) {
            ret = applications.get( key ) ;
            if( ret == null ) {
                if( ( ret = ScriptManager.getScript( name,currentDirectory ) ) != null ) {
                    applications.put( key,ret ) ;
                }
            }
        }
        if( ret == null ) {
            throw new HttpdStateException( HttpdErrorDef.HTTP11_500,
                "対象アプリケーション名["+name+"]は存在しません" ) ;
        }
        return ret ;
    }
    
    /**
     * 指定アプリケーションスクリプトが存在するかチェック.
     * <BR><BR>
     * 指定されたアプリケーションスクリプトが存在するかチェックします.
     * <BR>
     * @param name 対象名を設定します.
     * @return boolean [true]の場合、存在します.
     */
    public boolean isApplication( String name ) {
        boolean ret = false ;
        try {
            getApplication( name ) ;
            ret = true ;
        } catch( Exception e ) {
            ret = false ;
        }
        return ret ;
    }
    
    /**
     * カレントディレクトリを取得.
     * <BR><BR>
     * 設定されているカレントディレクトリを取得します.
     * <BR>
     * @return String カレントディレクトリが返されます.
     */
    public String getCurrentDirectory() {
        return currentDirectory ;
    }
}

