/*
 * WeberLogicDispatcher.java
 *
 * Created on 2007/01/28, 7:50
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package org.itscool.weber.controller;

import java.util.ArrayList;
import java.util.StringTokenizer;
import org.itscool.commons.util.StringUtil;
import org.itscool.weber.action.*;
import org.itscool.weber.user.User;

/**
 * リクエストパスから、アクション、フォームオブジェクト名
 * アクション実行後の遷移先URLを生成するクラスです<br>
 * @author kanou
 */
public class RequestDispatcher {
    /**
     * リクエストパス
     */
    private String fullPath = "";
    /**
     * Webアプリケーションのルートディレクトリ、モジュール名、アクション名を
     * 除いたパス情報
     */
    private String etcPath = "";
    /**
     * モジュール名（リクエストパスの最後のパス情報)
     */
    private String moduleName = "";
    /**
     * アクション名（拡張子を除いたもの)
     */
    private String actionName = "";
    
    /**
     * リクエストURL情報からモジュール名、アクション名を解析します
     * <br>
     * 例） 例えば、以下のリクエストURLから取得されるモジュール名、アクション名は
     * <br>
     * http://localhost/web-app-root/web-root/module_name/action_name.wb
     * <br>
     * フォームBean名=ModuleName<br>
     * アクション名=ActionNameAction<br>
     * となります
     * @param path リクエストURL
     */
    public RequestDispatcher(String path){
        this.fullPath = path;
        StringTokenizer st = new StringTokenizer(path, "/");
        ArrayList tokens = new ArrayList();
        while(st.hasMoreElements()){
            String element = (String)st.nextElement();
            tokens.add(element);
        }
        int tokenSize = tokens.size();
        
        if(tokenSize < 2){
            //ありえないケース
            return;
        }else if( tokenSize == 2){
            moduleName = (String)tokens.get(0);
            actionName = (String)tokens.get(1);
        }else{
            //モジュール名を取得
            moduleName = (String)tokens.get(tokenSize-2);
            //アクション名を取得（この時点では"."がついている)
            actionName = (String)tokens.get(tokenSize-1);
            //リクエストパスからモジュール名、アクション名を除去したパスを取得
            for(int i=0; i<tokenSize-2; i++){
                etcPath += (String)tokens.get(i) + "/";
            }
        }
        
        if( moduleName.length() == 1 ){
            moduleName = moduleName.toUpperCase();
        }else{
            moduleName = moduleName.substring(0,1).toUpperCase() + 
                moduleName.substring(1, moduleName.length());
        }
        //actionNameから拡張子を除去
        int lastDotPos = actionName.lastIndexOf(".");
        if( lastDotPos >= 1 ){
            if( actionName.length() == 1 ){
                actionName = actionName.toUpperCase();
            }else{
                actionName = actionName.substring(0, lastDotPos);
                //頭文字を大文字に変換
                actionName = actionName.substring(0,1).toUpperCase() + 
                    actionName.substring(1, actionName.length());
            }
        }
        
        moduleName = StringUtil.cnvUnderScorNameToUpperName(moduleName);
        actionName = StringUtil.cnvUnderScorNameToUpperName(actionName);
        
    }
    
    /**
     * パッケージ名付きアクション名を取得します
     * @param pkgName パッケージ名
     * @return パッケージ名.アクションクラス名を返します
     */
    public String getPkgActionName(String pkgName){
        if( (moduleName + actionName).equals("WeberLogin") ){
            return LoginAction.class.getName();
        }else if((moduleName + actionName).equals("WeberLogout")){
            return LogoutAction.class.getName();
        }else if( StringUtil.cnvUpperNameToUnderScoreName(actionName).equals("no_operation")){
            return NoOpAction4x.class.getName();
        }
        String clazzName = pkgName + "." + StringUtil.cnvUpperNameToUnderScoreName(moduleName) + "." +
            moduleName + actionName + "Action";
        
        return clazzName;
    }
    
    /**
     * パッケージ名付きフォームオブジェクト名を取得します
     * @param pkgName パッケージ名
     * @return パッケージ名.フォームオブジェクトクラス名を返します
     */
    public String getFormName(String pkgName){
        if( (moduleName + actionName).equals("WeberLogin") ){
            return User.class.getName();
        }else if((moduleName + actionName).equals("WeberLogout")){
            return User.class.getName();
        }else if( actionName.equals("no_operation")){
            return null;
        }
        String clazzName = pkgName + "."+ StringUtil.cnvUpperNameToUnderScoreName(moduleName) + "."
            + moduleName;
        
        return clazzName;
    }
    
    /**
     * モジュール名を取得します
     * @return モジュール名
     */
    public String getModuleName() {
        return moduleName;
    }
    
    /**
     * アクション名を取得します
     * @return アクション名
     */
    public String getActionName() {
        return actionName;
    }
    
    /**
     * アクションの実行結果から遷移先URLを取得します<br/>
     * たとえばアクションの実行結果が"regist"、モジュール名が"message"の場合
     * 遷移先URLは"リクエスト時のパス/message/message_regist.html"を
     * 返します。
     * @param ret アクションの実行結果
     * @return 遷移先URL
     */
    public String getReturnPath(String ret){
        String returnName = "";
        String moduleActionName;
        if(ret == null || ret.trim().length() == 0 ){
            returnName = "/" + etcPath + StringUtil.cnvUpperNameToUnderScoreName(moduleName) + "/";
            moduleActionName = moduleName + actionName;
            returnName =  returnName + StringUtil.cnvUpperNameToUnderScoreName(moduleActionName);
            return returnName;
        }else if(ret.length()==1){
            ret = ret.toUpperCase();
        }else{
            ret = ret.substring(0,1).toUpperCase() + 
                ret.subSequence(1, ret.length());
        }
        if( ret.toLowerCase().equals(Globals.REQ_PARAM_FORM_ERR)){
            //入力エラー時は呼出もとのアクション名とする
            returnName = "/" + etcPath + StringUtil.cnvUpperNameToUnderScoreName(moduleName) + "/";
            moduleActionName = moduleName + actionName;
            returnName = returnName + StringUtil.cnvUpperNameToUnderScoreName(moduleActionName);
        }else if( (moduleName + actionName).equals("WeberLogin") ){
            returnName = "/" + etcPath + StringUtil.cnvUpperNameToUnderScoreName(moduleName) + "/";
            moduleActionName = moduleName + actionName + ret;
            returnName = returnName + StringUtil.cnvUpperNameToUnderScoreName(moduleActionName);
        }else if((moduleName + actionName).equals("WeberLogout")){
            returnName = "/" + etcPath + StringUtil.cnvUpperNameToUnderScoreName(moduleName) + "/";
            moduleActionName = moduleName + actionName + ret;
            returnName = returnName + StringUtil.cnvUpperNameToUnderScoreName(moduleActionName);
        }else{
            
            int moduleIdx = ret.indexOf("/");
            if( moduleIdx >= 0 ){    //別モジュールのページに遷移する場合
                String anotherModuleName = ret.substring(0, moduleIdx);
                anotherModuleName =  StringUtil.cnvUpperNameToUnderScoreName(anotherModuleName);
                
                int retLen = ret.length();
                String anotherRetName = ret.substring(moduleIdx+1, retLen);
                
                returnName = "/" + etcPath + anotherModuleName + "/";
                returnName =  returnName + anotherModuleName + "_" + anotherRetName;
            
            }else{
                returnName = "/" + etcPath + StringUtil.cnvUpperNameToUnderScoreName(moduleName) + "/";
                moduleActionName = moduleName + ret;
                returnName =  returnName + StringUtil.cnvUpperNameToUnderScoreName(moduleActionName);
            }
        }
        return returnName;
    }
}
