/*
 * MosP - Mind Open Source Project         http://www.mosp.jp/
 * Copyright (C) 1987-2009 MIND Co., Ltd.  http://www.e-mind.co.jp/
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package jp.mosp.common.common;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.net.SocketException;
import java.util.List;
import java.util.Properties;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.ParserConfigurationException;

import jp.cloudzero.mosp.exception.CloudzeroUnsupportedException;
import jp.getset.gae.GaeUnsupportedException;

/**
 * MospフレームワークのFrontController。<br><br>
 *  
 * このサーブレットがMosPのContorollerとしての役割を果たす。<br>
 * 設定ファイル読込、例外処理の他に、以下の流れでアプリケーションを制御する機能を有する。<br>
 * <ul>
 * <li>リクエストの受付、及び共通前処理</li>
 * <li>Actionインスタンスの生成、及び処理実行</li>
 * <li>Viewへの処理委譲、或いはレスポンスの生成</li>
 * </ul>
 * 処理を実行するActionクラスは、リクエストに含まれるCommandによって決定される。<br>
 * ActionとCommandは、設定ファイルcontroller.propertiesによって関連付けられる。<br>
 * <br>
 * レスポンス形式は、HTTPリクエストパラメータ「resType」により決定される。<br>
 * 「resType」が「html」であれば、HTTPリクエストの属性({@link MospConst#ATT_URL})に
 * 設定されたURLにリクエストがフォワードされ、HTMLでレスポンスが送出される。<br>
 * 「resType」が「file」であれば、HTTPリクエストの属性({@link MospConst#ATT_FILE_OBJECT})
 * に設定されたオブジェクトをファイルとして送出する。<br>
 */
public class Controller extends HttpServlet {
	
	private static final long serialVersionUID = 5986464246296477656L;
	
	private transient ServletContext ctx = null;
	private Properties ctl = null;
	private Properties cfg = null;
	private Properties nam = null;
	private Properties msg = null;
	
	/**
	 * 初期化処理。<br>
	 * サーブレットコンテキスト取得、及び設定ファイル読込を行う。<br>
	 */
	@Override
	public void init(ServletConfig config) throws ServletException {
		try {
			super.init(config);
			// サーブレットコンテキストの取得
			if (ctx == null) {
				ctx = config.getServletContext();
			}
			// プロパティファイル読込
			getResources();
			// MosPフレームワークバージョンログ出力
			LogUtility.log(cfg, "", "", "", 4, MospConst.LOG_MOSPINF,
					MospConst.LOG_MSG_MOSP_VERSION + MospUtility.getMospJarVersion());
			// MosPSEユーティリティー存在確認
			try {
				Thread.currentThread().getContextClassLoader().loadClass("jp.mosp.se.SeUtility").newInstance();
				String seVer = jp.mosp.se.SeUtility.getMospSeJarVersion();
				ctx.setAttribute(MospConst.ATT_SE_VER, seVer);
				// MosPSEユーティリティーバージョンログ出力
				LogUtility.log(cfg, "", "", "", 4,
						MospConst.LOG_MOSPINF, MospConst.LOG_MSG_SE_VERSION + seVer);
			} catch(ClassNotFoundException e) {
				// MosPSEユーティリティー不使用
				ctx.removeAttribute(MospConst.ATT_SE_VER);
			}
			// MosP法定ユーティリティー存在確認
			try {
				Thread.currentThread().getContextClassLoader().loadClass("jp.mosp.legal.LegalUtility").newInstance();
				String legalVer = jp.mosp.legal.LegalUtility.getMospLegalJarVersion();
				ctx.setAttribute(MospConst.ATT_LEGAL_VER, legalVer);
				// MosP法定ユーティリティーバージョンログ出力
				LogUtility.log(cfg, "", "", "", 4,
						MospConst.LOG_MOSPINF, MospConst.LOG_MSG_LEGAL_VERSION + legalVer);
			} catch(ClassNotFoundException e) {
				// MosP法定ユーティリティー不使用
				ctx.removeAttribute(MospConst.ATT_LEGAL_VER);
			}
			// MosP計算式ユーティリティー存在確認
			try {
				Thread.currentThread().getContextClassLoader().loadClass("jp.mosp.express.ExpressUtility").newInstance();
				String expressVer = jp.mosp.express.ExpressUtility.getMospExpressJarVersion();
				ctx.setAttribute(MospConst.ATT_EXPRESS_VER, expressVer);
				// MosP計算式ユーティリティーバージョンログ出力
				LogUtility.log(cfg, "", "", "", 4,
						MospConst.LOG_MOSPINF, MospConst.LOG_MSG_EXPRESS_VERSION + expressVer);
			} catch(ClassNotFoundException e) {
				// MosP計算式ユーティリティー不使用
				ctx.removeAttribute(MospConst.ATT_EXPRESS_VER);
			}
			// Poiライブラリ存在確認
			try {
				Thread.currentThread().getContextClassLoader().loadClass("org.apache.poi.hssf.usermodel.HSSFWorkbook").newInstance();
				ctx.setAttribute(MospConst.ATT_POI_EXIST, Boolean.valueOf(true));
			} catch(ClassNotFoundException e) {
				// Poiライブラリ不使用
				ctx.removeAttribute(MospConst.ATT_POI_EXIST);
			}
			// jOpenDocumentライブラリ存在確認
			try {
				Thread.currentThread().getContextClassLoader().loadClass("org.jopendocument.dom.ODPackage").newInstance();
				ctx.setAttribute(MospConst.ATT_JOD_EXIST, Boolean.valueOf(true));
			} catch(ClassNotFoundException e) {
				// Poiライブラリ不使用
				ctx.removeAttribute(MospConst.ATT_JOD_EXIST);
			}
			// JasperReportライブラリ存在確認
			try {
				Thread.currentThread().getContextClassLoader().loadClass("net.sf.jasperreports.engine.JasperPrint").newInstance();
				ctx.setAttribute(MospConst.ATT_JASPER_EXIST, Boolean.valueOf(true));
			} catch(ClassNotFoundException e) {
				// JasperReportライブラリ不使用
				ctx.removeAttribute(MospConst.ATT_JASPER_EXIST);
			}
			// FileUploadライブラリ存在確認
			try {
				Thread.currentThread().getContextClassLoader().loadClass("org.apache.commons.fileupload.servlet.ServletFileUpload").newInstance();
				ctx.setAttribute(MospConst.ATT_UPLOAD_EXIST, Boolean.valueOf(true));
			} catch(ClassNotFoundException e) {
				// FileUploadライブラリ不使用
				ctx.removeAttribute(MospConst.ATT_UPLOAD_EXIST);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Getメソッドリクエスト取得処理。<br>
	 * 画像取得時にのみ用い、それ以外の場合はdoPost(request, response)を用いる。<br>
	 */
	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response) {
		try {
			// レスポンスタイプ等取得
			String responseType = request.getParameter(MospConst.PRM_RESPONSE_TYPE);
			String cmd          = request.getParameter(MospConst.PRM_CMD);
			String procSeq      = request.getParameter(MospConst.PRM_PROC_SEQ);
			// レスポンスタイプ等確認
			if (responseType == null || cmd == null || procSeq == null) {
				request.setAttribute(MospConst.ATT_CFG, cfg);
				throw new MospException(MospConst.EX_REQUEST_TYPE);
			}
			// イメージの場合
			if (responseType.equals(MospConst.RESPONSE_TYPE_IMAGE)) {
				doPost(request, response);
				return;
			}
			// Mobileの場合
			if (responseType.equals(MospConst.RESPONSE_TYPE_HTML)
					&& MobileUserUtility.isMobileUser(request)) {
				doPost(request, response);
				return;
			}
			// リクエストタイプ不正例外発行
			request.setAttribute(MospConst.ATT_CFG, cfg);
			throw new MospException(MospConst.EX_REQUEST_TYPE);
		} catch (Exception e) {
			handleException(e, request, response);
		}
	}
	
	/**
	 * Postメソッドリクエスト取得処理。<br>
	 * Contorollerのメインとなる処理を行い、アプリケーションを制御する。<br>
	 * クライアントは、このメソッドが実行されるようにHTTPリクエストを投げる必要がある。<br>
	 */
	@Override
	public void doPost(HttpServletRequest request, HttpServletResponse response) {
		try {
			// サーブレット前処理
			doCommonPreProcess(request);
			// アクセスログ出力
			LogUtility.log(request, 0, MospConst.LOG_ACCESS, "");
			// コマンドの取得
			String cmd = (String)request.getAttribute(MospConst.ATT_CMD);
			// アクションクラスの取得及び初期化
			ActionInterface action = (ActionInterface)MospUtility.getInstance(ctl, cmd);
			action.init(request, response);
			// アクション実行
			action.doAction();
			// アクション破棄
			action = null;
			// フォワード
			forward(request, response);
		} catch (Exception e) {
			handleException(e, request, response);
		} catch (Error e) {
			handleException(e, request, response);
		}
	}
	
	/**
	 * プロパティファイル群読込処理
	 * @throws IOException
	 */
	private void getResources() throws IOException {
		String docbase = ctx.getRealPath("");
		// 設定ファイルの取得
		cfg = MospUtility.getResource(docbase + MospConst.PATH_INF + MospConst.FILE_CFG);
		MospUtility.addResources(cfg, docbase + MospConst.PATH_INF, MospConst.FILE_EXT);
		cfg.setProperty(MospConst.PPT_APP_DOCBASE, docbase);
		// コントローラーファイルの取得
		ctl = MospUtility.getResource(docbase + MospConst.PATH_INF + MospConst.FILE_CTL);
		MospUtility.addResources(ctl, docbase + MospConst.PATH_INF, MospConst.FILE_CTL);
		// 文言ファイルの取得
		try {
			nam = MospUtility.getResource(docbase + MospConst.PATH_INF + MospConst.FILE_NAM);
		} catch (IOException e) {
			// 文言ファイルが存在しない場合
			nam = new Properties();
		}
		MospUtility.addResources(nam, docbase + MospConst.PATH_INF, MospConst.FILE_NAM);
		// メッセージファイルの取得
		msg = MospUtility.getResource(docbase + MospConst.PATH_INF + MospConst.FILE_MSG);
		MospUtility.addResources(msg, docbase + MospConst.PATH_INF, MospConst.FILE_MSG);
		// ==========
		// GAE対応 :
		// ファイル出力は不可
		// ==========
		// メッセージファイル(javascript)の出力
//		MospUtility.convProperties(msg, cfg.getProperty(MospConst.PPT_APP_DOCBASE) + MospConst.JS_MESSAGE, MospConst.JS_MESSAGE_NAME);
	}
	
	/**
	 * フォワード処理
	 * @param request リクエスト
	 * @param response レスポンス
	 * @throws IOException
	 * @throws ServletException
	 * @throws MospException
	 */
	private void forward(
			HttpServletRequest  request ,
			HttpServletResponse response
	) throws IOException, ServletException, MospException {
		String url = null;
		// レスポンスタイプ取得
		String responseType = (String)request.getAttribute(MospConst.ATT_RESPONSE_TYPE);
		// レスポンスタイプ毎にURLを設定
		if (responseType == null) {
			// 初期ページのURL若しくはエラーページのURL(nullの場合)
			url = (String)request.getAttribute(MospConst.ATT_URL);
			if (url == null || !url.equals(MospConst.URL_INDEX)) {
				url = MospConst.URL_ERROR;
			}
		} else if (responseType.equals(MospConst.RESPONSE_TYPE_HTML)) {
			// リクエストにセットしてあるURL(HTMLの場合)
			url = (String)request.getAttribute(MospConst.ATT_URL);
		} else if (responseType.equals(MospConst.RESPONSE_TYPE_XML)) {
			// XML出力ページ(XMLの場合)
			url = MospConst.URL_XML;
		} else if (responseType.equals(MospConst.RESPONSE_TYPE_FILE)) {
			// ファイル出力(テキストファイルあるいはExcelファイルの場合)
			Object objFile = request.getAttribute(MospConst.ATT_FILE_OBJECT);
			String strFile = (String)request.getAttribute(MospConst.ATT_FILE_NAME);
			response.setContentType(MospConst.RESPONSE_CONT_TYPE_FILE);
			response.setHeader(MospConst.RESPONSE_HEADER_FILE, MospConst.RESPONSE_HEADER_VALUE_FILE + strFile);
			if (objFile instanceof String || objFile instanceof StringBuffer) {
				// テキストファイルの場合
				PrintWriter pw = response.getWriter();
				pw.print(objFile);
			} else {
				// テキストファイル以外の場合
				// ライブラリー存在確認
				boolean hasPoi          = true;
				boolean hasJOpenDoc     = true;
				boolean hasJasperReport = true;
				if (ctx.getAttribute(MospConst.ATT_POI_EXIST) == null) {
					hasPoi = false;
				}
				if (ctx.getAttribute(MospConst.ATT_JOD_EXIST) == null) {
					hasJOpenDoc = false;
				}
				if (ctx.getAttribute(MospConst.ATT_JASPER_EXIST) == null) {
					hasJasperReport = false;
				}
				// ファイル出力
				if (hasPoi && objFile instanceof org.apache.poi.hssf.usermodel.HSSFWorkbook) {
					org.apache.poi.hssf.usermodel.HSSFWorkbook workbook = (org.apache.poi.hssf.usermodel.HSSFWorkbook)objFile;
					workbook.write(response.getOutputStream());
				} else if (hasJOpenDoc && objFile instanceof org.jopendocument.dom.spreadsheet.SpreadSheet) {
					org.jopendocument.dom.spreadsheet.SpreadSheet spreadSheet = (org.jopendocument.dom.spreadsheet.SpreadSheet)objFile;
					spreadSheet.getPackage().save(response.getOutputStream());
				} else if (hasJasperReport && objFile instanceof net.sf.jasperreports.engine.JRExporter) {
					net.sf.jasperreports.engine.JRExporter exporter = (net.sf.jasperreports.engine.JRExporter)objFile;
					exporter.setParameter(net.sf.jasperreports.engine.JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());
					try {
						exporter.exportReport();
					} catch(Exception e) {
						throw new MospException(MospConst.EX_RUNTIME_ERR);
					}
				} else {
					PrintWriter pw = response.getWriter();
					pw.print(objFile);
				}
			}
			return;
		} else if (responseType.equals(MospConst.RESPONSE_TYPE_IMAGE)) {
			// イメージファイルの場合
			Object objFile = request.getAttribute(MospConst.ATT_FILE_OBJECT);
			response.setContentType(MospConst.RESPONSE_CONT_TYPE_IMAGE);
		    ServletOutputStream out = response.getOutputStream();
		    byte[] data = new byte[1024];
		    int len;
		    BufferedInputStream in = (BufferedInputStream)objFile;
		    while ((len = in.read(data, 0, 1024)) != -1) {
		        out.write(data, 0, len);
		    }
		    in.close();
			return;
		} else {
			// エラーページのURL(その他の場合)
			url = MospConst.URL_ERROR;
		}
		if (url == null) {
			url = MospConst.URL_ERROR;
			LogUtility.log(request, 6, MospConst.LOG_MOSPERR, MospConst.LOG_MSG_NO_URL);
		}
		RequestDispatcher rd = ctx.getRequestDispatcher(url);
		rd.forward(request, response);
	}
	
	/**
	 * 共通前処理
	 * @param request リクエスト
	 * @throws Exception
	 */
	private void doCommonPreProcess(
			HttpServletRequest  request
	) throws Exception {
		// リクエストへのセット
		request.setAttribute(MospConst.ATT_CTX, ctx);
		request.setAttribute(MospConst.ATT_CTL, ctl);
		request.setAttribute(MospConst.ATT_CFG, cfg);
		request.setAttribute(MospConst.ATT_NAM, nam);
		request.setAttribute(MospConst.ATT_MSG, msg);
		// リクエストボディー部のバイト長確認
		if (MospConst.CONTENT_MAX_LEN < request.getContentLength()) {
			throw new MospException(MospConst.EX_CONTENT_LENGTH);
		}
		// プロパティファイル読込(app.hot=0時のみ)
		Properties hot = MospUtility.getResource(
				cfg.getProperty(MospConst.PPT_APP_DOCBASE) + MospConst.PATH_INF + MospConst.FILE_HOT);
		if (hot.getProperty(MospConst.PPT_APP_HOT).equals("0")) {
			getResources();
			LogUtility.setLevel(cfg);
		}
		// nextcmdによるリクエスト回数確認
		Integer forward = (Integer)request.getAttribute(MospConst.ATT_FORWARD);
		forward = forward != null ? forward : new Integer(0);
		if (forward.intValue() > 1) {
			throw new MospException(MospConst.EX_COUNT_FORWARD);
		}
		// リクエスト文字列の文字コード指定
		String contentType = request.getHeader("content-type");
		if (contentType != null && contentType.indexOf("charset") == -1) {
			request.setCharacterEncoding(MospConst.REQUEST_CHAR_ENC);
		}
		// Multipart確認
		List<?> multipartFieldList = null;
		if (ctx.getAttribute(MospConst.ATT_UPLOAD_EXIST) != null) {
			multipartFieldList = FileUploadUtility.getMultipartFieldList(request);
		}
		request.setAttribute(MospConst.ATT_MULTIPART_LIST, multipartFieldList);
		// レスポンスタイプ取得
		String responseType = (String)request.getAttribute(MospConst.ATT_RESPONSE_TYPE);
		if (responseType == null) {
			responseType = request.getParameter(MospConst.PRM_RESPONSE_TYPE);
		}
		if (responseType == null && multipartFieldList != null) {
			responseType = FileUploadUtility.getMultipartField(multipartFieldList, MospConst.PRM_RESPONSE_TYPE);
		}
		// レスポンスタイプ確認
		if (responseType == null) {
			throw new MospException(MospConst.EX_RESTYPE_NULL);
		} else if (
				!responseType.equals(MospConst.RESPONSE_TYPE_HTML) &&
				!responseType.equals(MospConst.RESPONSE_TYPE_FILE) &&
				!responseType.equals(MospConst.RESPONSE_TYPE_XML)  &&
				!responseType.equals(MospConst.RESPONSE_TYPE_IMAGE)
		) {
			throw new MospException(MospConst.EX_RESTYPE_INVALID);
		}
		// リクエストへのセット
		request.setAttribute(MospConst.ATT_RESPONSE_TYPE, responseType);
		// コマンド確認
		String cmd = (String)request.getAttribute(MospConst.ATT_NEXTCMD);
		request.removeAttribute(MospConst.ATT_NEXTCMD);
		if (cmd == null) {
			cmd = request.getParameter(MospConst.PRM_CMD);
			if (cmd == null) {
				cmd = FileUploadUtility.getMultipartField(multipartFieldList, MospConst.PRM_CMD);
			}
			if (cmd == null) {
				throw new MospException(MospConst.EX_CMD_NULL);
			}
			request.removeAttribute(MospConst.ATT_FORWARD);
		} else {
			request.setAttribute(MospConst.ATT_FORWARD, new Integer(forward.intValue() + 1));
		}
		if (cmd.length() > MospConst.LEN_COMMAND) {
			throw new MospException(MospConst.EX_CMD_FORMAT);
		}
		// リクエストへのセット
		request.setAttribute(MospConst.ATT_CMD, cmd);
	}
	
	/**
	 * サーブレットエラー処理
	 * @param ex 例外あるいはエラーオブジェクト
	 * @param request リクエスト
	 * @param response レスポンス
	 */
	private void handleException(
			Object             obj,
			HttpServletRequest request,
			HttpServletResponse response
	) {
		try {
			if (response.isCommitted()) {
				return;
			}
			String url = MospConst.URL_ERROR;
			HttpSession session = request.getSession(false);
			String responseType = (String)request.getAttribute(MospConst.ATT_RESPONSE_TYPE);
			if (obj instanceof MospException) {
				MospException me = (MospException)obj;
				int           exCode   = me.getExCode();
				int           logLevel = getExLogLevel(exCode);
				String        logType  = getExLogType(exCode);
				StringBuffer  message  = new StringBuffer();
				message.append(exCode);
				message.append("-");
				if (me.getExMessage() == null) {
					message.append(getExLogMessage(exCode));
				} else {
					message.append(me.getExMessage());
				}
//				LogUtility.log(request, logLevel, logType, message.toString());
				StringBuffer mes  = new StringBuffer();
				mes.append(me.getMessage());
				mes.append("\n");
				StackTraceElement[] sts = me.getStackTrace();
				for (StackTraceElement st : sts) {
					mes.append(st.toString());
					mes.append("\n");
				}
				LogUtility.log(request, logLevel, logType, mes.toString());
				if (needInitSession(exCode)) {
					if (session != null) {
						session.invalidate();
					}
					request.getSession(true);
				}
				url = getUrl(exCode, request);
			} else if (obj instanceof Exception) {
				Exception ex = (Exception)obj;
				LogUtility.outputErrorLog(ex, request);
				if (ex.getCause() instanceof SocketException && responseType.equals(MospConst.RESPONSE_TYPE_FILE)) {
					return;
				}
				if (session != null) {
					session.invalidate();
				}
				request.getSession(true);
				if (obj instanceof CloudzeroUnsupportedException) {
					url = "/jsp/common/error_cloudzero.jsp";
					request.setAttribute("exception", obj);
				} else if (obj instanceof GaeUnsupportedException) {
					url = "/jsp/common/error_gae.jsp";
					request.setAttribute("exception", obj);
				} else {
					url = MospConst.URL_ERROR;
				}
			} else if (obj instanceof Error) {
				Error er = (Error)obj;
				LogUtility.outputErrorLog(er, request);
				if (session != null) {
					session.invalidate();
				}
				request.getSession(true);
				url = MospConst.URL_ERROR;
			}
			request.setAttribute(MospConst.ATT_URL, url);
			// レスポンスタイプ毎の処理
			if (responseType != null && responseType.equals(MospConst.RESPONSE_TYPE_FILE)) {
				// レスポンスタイプをHTMLに変更(FILEの場合)
				request.setAttribute(MospConst.ATT_RESPONSE_TYPE, MospConst.RESPONSE_TYPE_HTML);
			} else if (responseType != null && responseType.equals(MospConst.RESPONSE_TYPE_XML)) {
				// XML用エラーコード設定(XMLの場合)
				setXmlErrCode(obj, request);
			}
			forward(request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * XMLレスポンスエラーコード設定
	 * @param ex 例外
	 * @param request リクエスト
	 * @throws ParserConfigurationException
	 */
	private void setXmlErrCode(
			Object ex,
			HttpServletRequest request
	) throws ParserConfigurationException {
		BaseVo vo = (BaseVo)request.getAttribute(MospConst.ATT_VO);
		if (vo == null) {
			vo = new BaseVo();
			request.setAttribute(MospConst.ATT_VO, vo);
		}
		vo.initXmlDoc();
		if (ex instanceof MospException) {
			MospException me = (MospException)ex;
			vo.setXmlRetCode(String.valueOf(me.getExCode()));
		} else {
			vo.setXmlRetCode(String.valueOf(MospConst.EX_RUNTIME_ERR));
		}
		if (vo.getDocXml() == null) {
			vo.initXmlDoc();
		}
	}

	/**
	 * 例外ログメッセージ取得
	 * @param exCode 例外コード
	 * @return 例外コードに対応するログメッセージ
	 */
	private String getExLogMessage(int exCode) {
		String message = "";
		try {
			Field field = MospConst.class.getField("LOG_MSG_" + String.valueOf(exCode));
			message = (String)field.get(null);
		} catch(NoSuchFieldException e) {
			message = MospConst.LOG_MSG_MESSAGE_ERROR;
		} catch(IllegalAccessException e) {
			message = MospConst.LOG_MSG_MESSAGE_ERROR;
		}
		return message;
	}
	
	/**
	 * 例外ログタイプ取得
	 * @param exCode 例外コード
	 * @return 例外コードに対応するログタイプ
	 */
	private String getExLogType(int exCode) {
		String logType = "";
		if (exCode >= 1000 && exCode < 4000) {
			logType = MospConst.LOG_MOSPINF;
		} else if (exCode >= 4000 && exCode < 5000) {
			logType = MospConst.LOG_SECURE;
		} else {
			logType = MospConst.LOG_MOSPERR;
		}
		return logType;
	}
	
	/**
	 * 例外ログレベル取得
	 * @param exCode 例外コード
	 * @return 例外コードに対応するログレベル
	 */
	private int getExLogLevel(int exCode) {
		int logLevel = 0;
		if (exCode >= 1000 && exCode < 4000) {
			logLevel = 4;
		} else if (exCode >= 4000 && exCode < 5000) {
			logLevel = 5;
		} else {
			logLevel = 6;
		}
		return logLevel;
	}
	
	/**
	 * セッション初期化要否
	 * @param exCode 例外コード
	 * @return 例外コードに対応するセッション初期化要否(true/false)
	 */
	private boolean needInitSession(int exCode) {
		if (exCode >= 1000 && exCode < 3000) {
			return false;
		}
		return true;
	}
	
	/**
	 * フォワード先取得
	 * @param exCode 例外コード
	 * @param request リクエスト
	 * @return 例外コードに対応するフォワード先
	 */
	private String getUrl(int exCode, HttpServletRequest request) {
		String url = "";
		if (exCode >= 1000 && exCode < 2000) {
			url = (String)request.getAttribute(MospConst.ATT_URL);
		} else if (exCode >= 2000 && exCode < 3000) {
			url = MospConst.URL_SRV;
		} else if (exCode >= 3000 && exCode < 4000) {
			url = MospConst.URL_INDEX;
		} else {
			url = MospConst.URL_ERROR;
		}
		return url;
	}
	
}
