package org.itscool.weber.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.itscool.commons.bean.BeanFactory;
import org.itscool.commons.bean.BeanUtil;
import org.itscool.commons.collection.InitParamMap;
import org.itscool.commons.dao.EntityInfoMapping;
import org.itscool.commons.logging.AbstractLog;
import org.itscool.commons.logging.SimpleLog;
import org.itscool.weber.action.*;
import org.itscool.weber.mapping.ExceptionMappings4x;

/**
 * scaffoladを実現するサーブレットクラスです<br>
 * 従来のFrontServlet機能を継承しつつ、リクエストURLからアクションとフォームオブジェクト
 * を自動的に検出し、処理します
 */
public class FrontServlet4x extends FrontServlet{
    
    /**
     * サーブレットが初期化されるときに呼ばれます<br>
     * 初期データを設定します
     * @param factory di-config.xmlファイルから初期設定情報を取得するインスタンス
     */
    public void initConfig(BeanFactory factory) throws ServletException {
        ExceptionMappings4x weber2Config = (ExceptionMappings4x)factory.createInstance("ExceptionMappings4x");
        try{
            log = (AbstractLog)factory.getInstance("Log");
            if(!log.isInit()){
                log = (AbstractLog)factory.createInstance("Log");
            }
            try{
                EntityInfoMapping daoMapping = (EntityInfoMapping)factory.createInstance("EntityInfoMapping");
            }catch(Exception ioe){
                log.info("DaoConfigReaderは実行されません");
            }
        }catch(Exception ioe){
            log = SimpleLog.getInstance();
            log.info(ioe.getMessage());
        }
    }
    
    /**
     * 業務処理を呼び出します
     * @param req HttpServletRequestインスタンス
     * @param res HttpServletResponseインスタンス
     * @return 実行結果を表示する画面URLを返します
     */
    protected String invoke(HttpServletRequest req, HttpServletResponse res)
    throws Exception{
        String returnPage = process(req, res);
        return returnPage;
    }
    
    /**
     * リクエストパスからActionインスタンスを取得します。
     * @param path リクエストパスを指定します
     * @return 生成されたActionインスタンス
     */
    public Action getAction(HttpServletRequest req, String path)
    throws IOException {
        ExceptionMappings4x config = (ExceptionMappings4x)ExceptionMappings4x.getInstance();
        BeanFactory factory = BeanFactory.getInstance();
        InitParamMap params = (InitParamMap)factory.createInstance("InitParams");
        String pkgName = params.getParam("pkgName");
        String fileType = params.getParam("fileType");
        RequestDispatcher pathInfo = new RequestDispatcher(path);
        String clazzName = pathInfo.getPkgActionName(pkgName);
        
//        System.out.println(clazzName);
        
        Action action = (Action) BeanUtil.createInstance(clazzName);
        
        action.setForwards(null);
        action.setValidates(null);
        
        return action;
    }
    
    /**
     * リクエストパスからFormBeanインスタンスを取得します。
     * @param path リクエストパスを指定します
     * @return 生成されたFormBeanインスタンス
     */
    public Object getForm(String path) throws IOException{
        ExceptionMappings4x config = (ExceptionMappings4x)ExceptionMappings4x.getInstance();
        
        BeanFactory factory = BeanFactory.getInstance();
        InitParamMap params = (InitParamMap)factory.getInstance("InitParams");
        String pkgName = params.getParam("pkgName");
        String fileType = params.getParam("fileType");
        RequestDispatcher pathInfo = new RequestDispatcher(path);
        String clazzName = pathInfo.getFormName(pkgName);
        if( clazzName == null ){
            return null;
        }
//        System.out.println(clazzName);
        
        Object bean=null;
        try{
            bean = (Object) BeanUtil.createInstance(clazzName);
        }catch(Exception e){
            
        }
        return bean;
    }
    
    /**
     * リクエストURIに指定された権限情報を取得します<BR>
     * 権限情報が定義されていないばあはNULLを返します
     * @param path リクエストされたURI情報
     * @return HashMap このアクションを許可する権限リストを返します
     */
    public HashMap getRoles(String path) {
        HashMap roles = new HashMap();
//        RequestMappings config = (RequestMappings)RequestMappings.getInstance();
//        String pkgName = config.getPkgName();
//        String fileType = config.getFileType();
//        RequestDispatcher pathInfo = new RequestDispatcher(path);
//        String moduleName = pathInfo.getModuleName();
//        String actionName = pathInfo.getActionName();
//        Map roleAction = config.getRolesAction();
//
//        Map roleModule = config.getRolesModule();
//        String roleName = (String)roleAction.get(moduleName+actionName);
//        if(roleName == null){
//            roleName = (String)roleModule.get(moduleName);
//        }
//        if(roleName != null){
//            roles.put(roleName, roleName);
//        }
        return roles;
    }
    
    /**
     * 業務処理実行後の遷移先URLを取得します
     * @param action Actionインスタンス
     * @param ret Actionの実行結果
     * @param path リクエストパス情報
     */
    protected String getForward(Action action, String ret, String path) throws ServletException {
        ExceptionMappings4x config = (ExceptionMappings4x)ExceptionMappings4x.getInstance();
        
        BeanFactory factory = BeanFactory.getInstance();
        InitParamMap params = (InitParamMap)factory.getInstance("InitParams");
        String pkgName = params.getParam("pkgName");
        String fileType = params.getParam("fileType");
        if(fileType.indexOf(".")!=0){
            fileType = "." + fileType;
        }
        RequestDispatcher pathInfo = new RequestDispatcher(path);
        String moduleName = pathInfo.getModuleName();
        String actionName = pathInfo.getActionName();
        String returnPath = pathInfo.getReturnPath(ret);
        returnPath += fileType;
        return returnPath;
    }
    
    /**
     * 例外発生時の遷移先URLを取得します
     * @param e Exception/Errorインスタンス
     * @return 例外発生時の遷移先URL
     */
    protected String getExceptionPage(Object e){
        ExceptionMappings4x config = (ExceptionMappings4x)ExceptionMappings4x.getInstance();
        Map exceptions = config.getExceptions();
        //KeyLinkedList exceptions = config.getExceptions();
        
        Set keySet = exceptions.keySet();
        Iterator it = keySet.iterator();
        String exceptionName = null;
        while(it.hasNext()){
            String key = (String)it.next();
            exceptionName = e.getClass().getName();
            if(key.equals(exceptionName)){
                break;
            }else{
                try{
                    Class clazz = Class.forName(key);
                    if(clazz.isInstance(e)){
//modify 2007/04/10 kano start
                        exceptionName = key;
//modify 2007/04/10 kano end
                        break;
                    }
                }catch(Exception ex){}
            }
        }
        String exceptionPage = (String)exceptions.get(exceptionName);
        return exceptionPage;
    }
}

