/*
 * MosP - Mind Open Source Project    http://www.mosp.jp/
 * Copyright (C) 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.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import jp.mosp.common.dao.CmCodeDao;
import jp.mosp.common.dto.CmAspUserDto;
import jp.mosp.common.dto.CmCodeDto;
import jp.mosp.common.dto.CmUserDto;

/**
 * Actionの基本機能を提供する。<br>
 * <br>
 * MosPフレームワークでは、Contorollerにより生成されたActionクラスの
 * インスタンスが、ビジネスロジックの実行、Viewの選択を行う。<br>
 * <br>
 * 各アプリケーションにおいて、当クラスを拡張してActionクラスを
 * 作成することで、MosPフレームワークを有効に利用できる。<br>
 * <br>
 * 拡張して作成したクラスでは{@link ActionInterface#action()}を実装し、
 * このメソッド内にビジネスロジックを記述することになる。
 * 
 */
public abstract class BaseAction extends DBConnBean implements ActionInterface {
	
	private boolean needHeader = true;
	private boolean needSession = true;
	private boolean needAspUser = true;
	private boolean needUser = true;
	private boolean checkProcSeq = true;
	private boolean needProcSeq = true;
	private boolean checkAuth = true;
	private String application = MospConst.APP_COMMON;
	private ArrayList<String> authorized;
	
	/**
	 * 受信したHTTPリクエスト。
	 */
	protected HttpServletRequest request;
	
	/**
	 * 送出するHTTPレスポンス。
	 */
	protected HttpServletResponse response;
	
	/**
	 * リクエストに紐付くHTTPセッション。
	 */
	protected HttpSession session;
	
	/**
	 * アプリケーションで共有するサーブレットコンテキスト。
	 */
	protected ServletContext ctx;
	
	/**
	 * コントローラー設定(/WEB-INF/controller.properties)。
	 */
	protected Properties ctl;
	
	/**
	 * MosPアプリケーション設定(/WEB-INF/mosp.properties)。
	 */
	protected Properties cfg;
	
	/**
	 * メッセージ設定(/WEB-INF/message.properties)。
	 */
	protected Properties msg;
	
	/**
	 * 文言設定(/WEB-INF/naming.properties)。
	 */
	protected Properties nam;
	
	/**
	 * ログインASPユーザー。
	 */
	protected CmAspUserDto aspUser;
	
	/**
	 * ログインユーザー。
	 */
	protected CmUserDto user;
	
	/**
	 * リクエストされたCommand。
	 */
	protected String cmd;
	
	/**
	 * Commandとともにリクエストされた汎用パラメータ。
	 */
	protected String key1;
	
	/**
	 * Commandとともにリクエストされた汎用パラメータ。
	 */
	protected String key2;
	
	/**
	 * Commandとともにリクエストされた汎用パラメータ。<br><br>
	 * リクエストがMultiPartの場合は、利用できない。<br>
	 */
	protected String[] key;
	
	/**
	 * リクエストパラメータリスト(multipartでリクエストされた場合)。
	 */
	protected List<?> multipartFieldList;
	
	private VoInterface vo;
	private String      url;
	private String      nextCmd;

	/**
	 * コンストラクタ。<br>
	 * DBコネクションの初期化を行う。
	 */
	public BaseAction() {
		super();
	}
	
	/**
	 * アクション初期化処理。<br>
	 * 各フィールドにオブジェクトを割り当てる。
	 * @param request  受信したHTTPリクエスト
	 * @param response 送出するHTTPレスポンス
	 */
	public void init(
			HttpServletRequest  request,
			HttpServletResponse response
	) throws Exception {
		// 情報の取得
		this.request  = request;
		this.response = response;
		this.ctx      = (ServletContext)request.getAttribute(MospConst.ATT_CTX);
		this.ctl      = (Properties    )request.getAttribute(MospConst.ATT_CTL);
		this.cfg      = (Properties    )request.getAttribute(MospConst.ATT_CFG);
		this.msg      = (Properties    )request.getAttribute(MospConst.ATT_MSG);
		this.nam      = (Properties    )request.getAttribute(MospConst.ATT_NAM);
		this.cmd      = (String        )request.getAttribute(MospConst.ATT_CMD);
		this.key1     = request.getParameter      (MospConst.PRM_KEY1);
		this.key2     = request.getParameter      (MospConst.PRM_KEY2);
		this.multipartFieldList = (List<?>)request.getAttribute(MospConst.ATT_MULTIPART_LIST);
		if (this.key1 == null && this.multipartFieldList != null) {
			this.key1 = FileUploadUtility.getMultipartField(multipartFieldList, MospConst.PRM_KEY1);
		}
		if (this.key2 == null && this.multipartFieldList != null) {
			this.key2 = FileUploadUtility.getMultipartField(multipartFieldList, MospConst.PRM_KEY2);
		}
		this.key      = request.getParameterValues(MospConst.PRM_KEY );
	}
	
	/**
	 * アクション実行処理。<br>
	 * 次の処理及びメソッドを実行する。
	 * <ul>
	 * <li>アクション前処理(各種チェック及び設定)</li>
	 * <li>action(各アプリケーションで実装)</li>
	 * <li>パラメータ設定(Viewに対する情報の設定)</li>
	 * <li>{@link #afterAction()}</li>
	 * </ul>
	 */
	public void doAction() throws Exception {
		try {
			// アクション前処理実行
			preAction();
			// アクション実行ログ出力
			LogUtility.log(request, 1, MospConst.LOG_ACTION, MospConst.ACTION_START);
			// アクション実行
			action();
			// アクション終了ログ出力
			LogUtility.log(request, 1, MospConst.LOG_ACTION, MospConst.ACTION_END);
			// 情報の設定
			setParams();
		} catch(Exception e) {
			// 情報の設定
			setParams();
			throw e;
		} finally {
			afterAction();
		}
	}
	
	/**
	 * アクション前処理。
	 * @throws Exception
	 */
	private void preAction() throws Exception {
		
		// レスポンスタイプ取得
		String responseType = (String)request.getAttribute(MospConst.ATT_RESPONSE_TYPE);
		// レスポンスヘッダーの設定
		if (needHeader) {
			// キャッシュ無効設定
			if (!responseType.equals(MospConst.RESPONSE_TYPE_FILE)) {
				response.setHeader("Pragma", "no-cache");
				response.setHeader("Cache-Control", "no-cache");
				response.addHeader("Cache-Control", "no-store"); 
			}
			response.setDateHeader("Expires", 0);
			// ContentType設定
			response.setContentType(MospConst.RESPONSE_CONT_TYPE_HTML);
		}
		
		// セッションの取得
		if (needSession) {
			session = request.getSession(false);
			if (session == null) {
				nextCmd = getIndexCommand(false);
				addList(bringErrMessage(),
						MospUtility.getMessage(msg, MospConst.MSG_SESSION_TIMEOUT, ""));
				throw new MospException(MospConst.EX_SESSION_TIMEOUT);
			}
			// セッションタイムアウト時間の設定
			int interval = Integer.parseInt(cfg.getProperty(MospConst.PPT_APP_INTERVAL));
			session.setMaxInactiveInterval(interval);
		}
		
		// ASPユーザーの取得
		if (needAspUser) {
			aspUser = (CmAspUserDto)session.getAttribute(MospConst.ATT_ASPUSER);
			if (aspUser == null) {
				nextCmd = getIndexCommand(false);
				throw new MospException(MospConst.EX_SESSION_INVALID);
			}
			request.setAttribute(MospConst.ATT_ASPUSER, aspUser);
		}
		
		// ユーザーの取得
		if (needUser) {
			user = (CmUserDto)session.getAttribute(MospConst.ATT_USER);
			if (user == null) {
				nextCmd = getIndexCommand(false);
				throw new MospException(MospConst.EX_SESSION_INVALID);
			}
			request.setAttribute(MospConst.ATT_USER, user);
		}
		
		// 処理シーケンス確認
		if (checkProcSeq) {
			String procSeq = (String)request.getAttribute(MospConst.ATT_PROC_SEQ);
			if (procSeq == null) {
				procSeq = request.getParameter(MospConst.PRM_PROC_SEQ);
				if (procSeq == null && this.multipartFieldList != null) {
					procSeq = FileUploadUtility.getMultipartField(
							multipartFieldList, MospConst.PRM_PROC_SEQ);
				}
			}
			if (procSeq == null) {
				throw new MospException(MospConst.EX_PROCSEQ_NULL);
			}
			String storedProcSeq = (String)session.getAttribute(MospConst.ATT_PROC_SEQ);
			if (!procSeq.equals(storedProcSeq)) {
				String rep     = procSeq + MospConst.DATA_SEPARATOR + storedProcSeq;
				String message = MospUtility.replace(MospConst.LOG_MSG_PROC_SEQ, rep);
				LogUtility.log(request, 4, MospConst.LOG_MOSPINF, message);
				nextCmd = getIndexCommand(true);
				throw new MospException(MospConst.EX_PROCSEQ_INVALID);
			}
		}
		
		// 権限確認
		if (checkAuth) {
			boolean hasAuth = false;
			String auth = null;
			if (application.equals(MospConst.APP_COMMON)) {
				auth = user.getMospAuthority();
			} else if (application.equals(MospConst.APP_PAYROLL)) {
				auth = user.getPayrollAuthority();
			} else if (application.equals(MospConst.APP_EXPENSE)) {
				auth = user.getExpenseAuthority();
			} else if (application.equals(MospConst.APP_SALES)) {
				auth = user.getSalesAuthority();
			} else if (application.equals(MospConst.APP_EXT1)) {
				auth = user.getExt1Authority();
			} else if (application.equals(MospConst.APP_EXT2)) {
				auth = user.getExt2Authority();
			} else if (application.equals(MospConst.APP_EXT3)) {
				auth = user.getExt3Authority();
			} else if (application.equals(MospConst.APP_EXT4)) {
				auth = user.getExt4Authority();
			} else if (application.equals(MospConst.APP_EXT5)) {
				auth = user.getExt5Authority();
			} else {
				throw new MospException(MospConst.EX_APP_PROPERTIES);
			}
			for(Iterator<String> it = authorized.iterator(); it.hasNext();) {
				if (it.next().equals(auth)) {
					hasAuth = true;
					break;
				}
			}
			if (!hasAuth) {
				throw new MospException(MospConst.EX_AUTHORITY);
			}
		}
		
	}
	
	/**
	 * アクション後処理。<br>
	 * {@link #rollback()}、{@link #releaseConnection()}等を行う。<br>
	 * @throws SQLException
	 */
	protected void afterAction() throws SQLException {
		// DBコネクション破棄
		rollback();
		releaseConnection();
		// セッション確認
		if (session == null) {
			return;
		}
		// 処理シーケンス発行
		String procSeq = null;
		if (needProcSeq) {
			procSeq = MospUtility.generateProcSeq(hasMospSeJar(),
					(String)session.getAttribute(MospConst.ATT_PROC_SEQ));
		} else {
			// 保存されている処理シーケンスを継承
			procSeq = (String)session.getAttribute(MospConst.ATT_PROC_SEQ);
		}
		// 処理シーケンス設定
		request.setAttribute(MospConst.ATT_PROC_SEQ, procSeq);
		session.setAttribute(MospConst.ATT_PROC_SEQ, procSeq);
		if (vo != null) {
			vo.setProcSeq(procSeq);
		}
	}
	
	/**
	 * DBコネクション取得。<br>
	 * {@link #aspUser}に設定された情報を用いて、
	 * {@link #getConnection(String, String, String, String)}
	 * を実行する。<br>
	 * @throws ClassNotFoundException
	 * @throws SQLException
	 */
	protected void getConnection() throws ClassNotFoundException, SQLException{
		if (conn == null || conn.isClosed()) {
			super.getConnection(
					aspUser.getDbDriver(),
					aspUser.getDbUrl()   ,
					aspUser.getDbUser()  ,
					aspUser.getDbPass()
			);
		}
	}
	
	/**
	 * 実行権限付与。<br>
	 * 当該Actionの実行権限を付与する。<br>
	 * {@link #setCheckAuth(boolean)}でtrueを設定している場合のみ有効。<br>
	 * @param authority 権限文字列
	 */
	protected void authorize(String authority) {
		authorized = authorized != null ? authorized : new ArrayList<String>();
		authorized.add(authority);
	}
	
	/**
	 * 情報の設定
	 */
	private void setParams() {
		if (nextCmd == null) {
			// VO及びフォワード先の設定
			String message = (String)request.getAttribute(MospConst.ATT_MESSAGE); 
			List<String> errMessage = bringErrMessage();
			if (message != null && vo != null) {
				vo.setMessage(message);
			}
			if (errMessage != null && vo != null) {
				for (int i = 0; i < errMessage.size(); i++) {
					vo.addErrMessage(errMessage.get(i));
				}
			}
			request.setAttribute(MospConst.ATT_VO, vo);
			request.setAttribute(MospConst.ATT_URL, url);
		} else {
			// コマンドの設定
			request.setAttribute(MospConst.ATT_URL, MospConst.URL_SRV);
			request.setAttribute(MospConst.ATT_NEXTCMD, nextCmd);
		}
	}
	
	/**
	 * メッセージを設定する。<br>
	 * {@link #request}にメッセージを設定する。
	 * @param strMessage メッセージ
	 */
	protected void setMessage(String strMessage) {
		request.setAttribute(MospConst.ATT_MESSAGE, strMessage);
	}
	
	/**
	 * エラーメッセージを設定する。<br>
	 * {@link #request}に収められたエラーメッセージリストに、
	 * メッセージを追加する。
	 * @param strErrMessage エラーメッセージ
	 */
	protected void addErrMessage(String strErrMessage) {
		addList(bringErrMessage(), strErrMessage);
	}
	
	/**
	 * エラーメッセージリストを取得する。<br><br>
	 * {@link #request}から、{@link MospConst#ATT_ERR_MESSAGE}をキーとして、取得する。<br>
	 * {@link #request}にエラーメッセージリストが存在しない場合、
	 * 空のエラーメッセージリストを{@link #request}に設定して返値とする。
	 * @return エラーメッセージリスト
	 */
	@SuppressWarnings("unchecked")
	private List<String> bringErrMessage() {
		Object obj = request.getAttribute(MospConst.ATT_ERR_MESSAGE);
		if (obj != null && obj instanceof List) {
			return (List)obj;
		}
		List<String> list = new ArrayList<String>(); 
		request.setAttribute(MospConst.ATT_ERR_MESSAGE, list);
		return list;
	}
	
	/**
	 * Vo保存(セッションに保存)。<br>
	 * {@link #session}にVOを格納する。<br>
	 * 保存したVoは、{@link #getStoredVo(String)}で取得できる。
	 * 複数の画面にわたって情報を保持する必要がある場合に利用する。<br>
	 * @param key 保存キー
	 * @param vo  保存対象Vo
	 */
	protected void storeVo(String key, VoInterface vo) {
		putMap(bringStoredVo(), key, vo);
		session.setAttribute(MospConst.ATT_FORMER_VO, vo);
	}
	
	/**
	 * 保存VO取得。<br>
	 * {@link #storeVo(String, VoInterface)}で保存したVoを取得する。<br>
	 * @param key 保存キー
	 * @return 取得VO
	 */
	protected VoInterface getStoredVo(String key) {
		return bringStoredVo().get(key);
	}

	/**
	 * 保存VO除去(storeVoによりセッションに保存したVOの除去)。<br>
	 * {@link #storeVo(String, VoInterface)}で保存したVOのうち、
	 * 不要になったものを除去する。<br>
	 * @param key 除去VOクラス名
	 */
	protected void removeStoredVo(String key) {
		bringStoredVo().remove(key);
	}
	
	/**
	 * 保存VO取得。<br><br>
	 * {@link #session}から、{@link MospConst#ATT_STORE_VO}をキーとして、
	 * 保存VOを取得する。<br>
	 * {@link #session}に保存VOが存在しない場合、空の保存VOを{@link #session}に
	 * 設定して返値とする。
	 * @return 保存VO
	 */
	@SuppressWarnings("unchecked")
	private Map<String, VoInterface> bringStoredVo() {
		Object obj = session.getAttribute(MospConst.ATT_STORE_VO);
		if (obj != null && obj instanceof Map) {
			return (Map)obj;
		}
		Map<String, VoInterface> map = new HashMap<String, VoInterface>(); 
		session.setAttribute(MospConst.ATT_STORE_VO, map);
		return map;
	}
	
	/**
	 * VOインスタンスの取得及び設定。<br><br>
	 * {@link BaseAction#prepareVo(boolean)}を実行する。引数はtrue。<br>
	 * @return 取得したVOインスタンス
	 * @throws MospException 
	 */
	protected BaseVo prepareVo() throws MospException {
		return prepareVo(true);
	}
	
	/**
	 * VOインスタンスの取得及び設定。<br><br>
	 * <ul><li>
	 * VOインスタンス取得<br>
	 * {@link #getSpecificVo()}で、処理対象VOインスタンスを取得する。<br><br>
	 * </li><li>
	 * 保存VO確認<br>
	 * {@link #getStoredVo(String)}で、VOインスタンスのクラス名をキーとして
	 * 保存VOを取得(無ければ{@link #storeVo(String, VoInterface)}で保存)する。<br><br>
	 * <li>
	 * VO初期化<br>
	 * {@link BaseVo#initVo(Properties, Properties, String, CmAspUserDto, CmUserDto)}、
	 * {@link BaseVo#clearMessage()}、{@link BaseVo#clearErrField()}を行う。<br><br>
	 * </li>
	 * <li>
	 * VO及びフォワード先URLの設定<br>
	 * {@link #setVo(VoInterface)}、{@link BaseVo#getRetUrl()}を引数として
	 * {@link #setUrl(String)}を行う。<br><br>
	 * </li></ul>
	 * @param useStoredVo 保持VO利用フラグ(true：保持VOを使う、false：保持VOがあろうと新規VOを使う)
	 * @return 取得したVOインスタンス
	 * @throws MospException 
	 */
	protected BaseVo prepareVo(boolean useStoredVo) throws MospException {
		// VOインスタンス取得
		BaseVo baseVo = getSpecificVo();
		if (baseVo == null) {
			return null;
		}
		// 保存VO確認
		Object storedVo = getStoredVo(baseVo.getClassName());
		if (storedVo != null && useStoredVo) {
			chkInstance(storedVo instanceof BaseVo);
			baseVo = (BaseVo)storedVo;
		}
		// VO保存
		storeVo(baseVo.getClassName(), baseVo);
		// VO初期化
		baseVo.initVo(cfg, msg, nam, cmd, aspUser, user);
		baseVo.clearMessage();
		baseVo.clearErrField();
		// VO及びフォワード先URLの設定
		setVo(baseVo);
		setUrl(baseVo.getRetUrl());
		return baseVo;
	}
	
	/**
	 * VO取得。<br><br>
	 * {@link #prepareVo()}で用いられる。<br>
	 * {@link BaseAction}を拡張したクラスでこのメソッドをオーバーライドすることで、
	 * {@link #prepareVo()}を用いて{@link BaseVo}を拡張した任意のVOインスタンスを
	 * 取得することができる。
	 * @return VOインスタンス
	 */
	protected BaseVo getSpecificVo() {
		return new BaseVo();
	}
	
	/**
	 * 保存データ初期化(セッションに保存したデータの初期化)。<br>
	 * アプリケーションが{@link #session}に保存した各種情報を初期化する。<br>
	 * 但し、ログイン情報等は初期化されない。<br>
	 * @throws 実行時例外
	 */
	protected void initStoredData() {
		session.removeAttribute(MospConst.ATT_STORE_VO );
		session.removeAttribute(MospConst.ATT_FORMER_VO);
		session.removeAttribute(MospConst.ATT_DTO      );
		session.removeAttribute(MospConst.ATT_LIST     );
	}
	
	/**
	 * データ存在確認。<br>
	 * dtoがnullの場合、{@link MospException}を発行する。<br>
	 * @param dto 確認対象DTO
	 * @throws MospException
	 */
	protected void chkExist(BaseDto dto) throws MospException {
		if (dto == null) {
			throw new MospException(MospConst.EX_NO_DATA);
		}
	}
	
	/**
	 * 更新確認。<br>
	 * dtoがnullの場合、{@link MospException}を発行する。<br>
	 * @param dto 確認対象DTO
	 * @throws MospException
	 */
	protected void chkUpdate(BaseDto dto) throws MospException {
		if (dto == null) {
			throw new MospException(MospConst.EX_UPDATE_FAILED);
		}
	}
	
	/**
	 * 挿入確認。<br>
	 * dtoがnullの場合、{@link MospException}を発行する。<br>
	 * @param dto 確認対象DTO
	 * @throws MospException
	 */
	protected void chkInsert(BaseDto dto) throws MospException {
		if (dto == null) {
			throw new MospException(MospConst.EX_INSERT_FAILED);
		}
	}
	
	/**
	 * データ重複確認。<br>
	 * dtoがnullでない場合、{@link MospException}を発行する。<br>
	 * @param dto 確認対象DTO
	 * @param vo データ存在時メッセージ設定VO
	 * @throws MospException
	 */
	protected void chkDuplicate(BaseDto dto, VoInterface vo) throws MospException {
		if (dto != null) {
			vo.addErrMessage(MospUtility.getMessage(msg, MospConst.MSG_DUPLICATE, ""));
			throw new MospException(MospConst.EX_DUPLICATE);
		}
	}
	
	/**
	 * 更新日時による排他確認。<br>
	 * currentDtoに対して{@link #chkExist(BaseDto)}を実行した後、
	 * formerDtoとcurrentDtoの更新日時を比較する。<br>
	 * 更新日時が同じでない場合、{@link MospException}を発行する。<br>
	 * @param formerDto 更新対象DTO(編集前)
	 * @param currentDto 更新対象DTO(最新)
	 * @param vo 更新日時相違時メッセージ設定VO
	 * @throws MospException
	 */
	protected void chkExclusive(BaseDto formerDto, BaseDto currentDto, VoInterface vo) throws MospException {
		chkExist(currentDto);
		if (formerDto.getUpdateDate().compareTo(currentDto.getUpdateDate()) != 0) {
			vo.addErrMessage(MospUtility.getMessage(msg, MospConst.MSG_EXCLUSIVE, ""));
			throw new MospException(MospConst.EX_EXCLUSIVE);
		}
	}
	
	/**
	 * コード存在確認。<br>
	 * dtoがnullの場合、{@link MospException}を発行し、
	 * 対象をエラーフィールドに加える。<br>
	 * @param dto 確認対象DTO
	 * @param targetId 確認対象フィールドID
	 * @param vo コード不在時メッセージ設定VO
	 * @throws MospException
	 */
	protected void chkCodeExist(BaseDto dto, String targetId, VoInterface vo) throws MospException {
		if (dto == null) {
			vo.addErrMessage(MospUtility.getMessage(msg, MospConst.MSG_NO_CODE, ""));
			vo.addErrField(targetId);
			throw new MospException(MospConst.EX_NO_CODE);
		}
	}
	
	/**
	 * コード存在確認(明細)。<br>
	 * dtoがnullの場合、{@link MospException}を発行し、
	 * 対象をエラーフィールドに加える。<br>
	 * @param dto 確認対象DTO
	 * @param rowNo 行番号
	 * @param targetId 確認対象フィールドID
	 * @param vo コード不在時メッセージ設定VO
	 * @throws MospException
	 */
	protected void chkCodeExist(BaseDto dto, int rowNo, String targetId, VoInterface vo) throws MospException {
		if (dto == null) {
			vo.addErrMessage(MospUtility.getMessage(msg, MospConst.MSG_NO_CODE, ""));
			vo.addErrDetails(rowNo, targetId);
			throw new MospException(MospConst.EX_NO_CODE);
		}
	}
	
	/**
	 * インスタンス確認。<br>
	 * isInstanceがfalseの場合、MospExceptionを発行する。
	 * @param isInstance instanceofによる演算結果
	 * @throws MospException 
	 */
	protected void chkInstance(boolean isInstance) throws MospException {
		if (!isInstance) {
			throw new MospException(MospConst.EX_WRONG_INSTANCE);
		}
	}
	
	/**
	 * コードリスト取得(CM_CODE)。<br>
	 * コードテーブルから特定のコード区分のリストを取得する。<br>
	 * @param tId コード区分
	 * @return コードリスト
	 * @throws Exception
	 */
	protected String[][] getCodeArray(String tId) throws Exception {
		try {
			// DBコネクションの取得及びDTOの準備
			getConnection();
			// DAOの宣言
			CmCodeDao dao = new CmCodeDao(cfg, cmd, aspUser, user, conn);
			// データの取得
			List<CmCodeDto> list = dao.findForCondition(tId);
			// データの整形
			String[][] array = new String[list.size()][2];
			for (int i = 0; i < list.size(); i++) {
				CmCodeDto dto = list.get(i);
				array[i][0] = dto.getTCode();
				array[i][1] = dto.getTName();
			}
			return array;
		} catch(Exception e) {
			throw e;
		} finally {
			// DBコネクション破棄
			rollback();
			releaseConnection();
		}
	}

	/**
	 * リスト追加。<br>
	 * リストにオブジェクトを追加するだけのメソッド。<br>
	 * @param list リスト
	 * @param obj  追加対象オブジェクト
	 */
	@SuppressWarnings("unchecked")
	protected void addList(List list, Object obj) {
		list.add(obj);
	}
	
	/**
	 * マップ追加。<br>
	 * マップにオブジェクトを追加するだけのメソッド。<br>
	 * @param map マップ
	 * @param key キーオブジェクト
	 * @param obj  追加対象オブジェクト
	 */
	@SuppressWarnings("unchecked")
	protected void putMap(Map map, Object key, Object obj) {
		map.put(key, obj);
	}
	
	/**
	 * ""付加
	 * @param data 付加対象データ
	 * @return 付加後文字列
	 */
	protected String getCsvData(String data) {
		if (data == null) {
			return "";
		}
		String newData = data.replaceAll("\"", "\"\"");
		return "\"" + newData + "\"";
	}
	
	/**
	 * ""付加
	 * @param data 付加対象データ
	 * @return 付加後文字列
	 */
	protected String getCsvData(int data) {
		return "\"" + String.valueOf(data) + "\"";
	}

	/**
	 * ""付加
	 * @param data 付加対象データ
	 * @return 付加後文字列
	 */
	protected String getCsvData(float data) {
		return "\"" + String.valueOf(data) + "\"";
	}
	
	/**
	 * ""付加
	 * @param data 付加対象データ
	 * @return 付加後文字列
	 */
	protected String getCsvData(Date data, String format) {
		if (data == null) {
			return "";
		}
		String newData = MospUtility.getDateString(data, format);
		return "\"" + newData + "\"";
	}
	
	/**
	 * MosPSEユーティリティー利用可否取得。<br>
	 * @return MosPSEユーティリティー利用可否(true：可、false：不可)
	 */
	protected boolean hasMospSeJar() {
		String seVer = (String)ctx.getAttribute(MospConst.ATT_SE_VER);
		if (seVer == null || seVer.equals("")) {
			return false;
		}
		return true;
	}
	
	/**
	 * MosP法定ユーティリティー利用可否取得。<br>
	 * @return MosP法定ユーティリティー利用可否(true：可、false：不可)
	 */
	protected boolean hasMospLegalJar() {
		String legalVer = (String)ctx.getAttribute(MospConst.ATT_LEGAL_VER);
		if (legalVer == null || legalVer.equals("")) {
			return false;
		}
		return true;
	}
	
	/**
	 * MosP計算式ユーティリティー利用可否取得。<br>
	 * @return MosP計算式ユーティリティー利用可否(true：可、false：不可)
	 */
	protected boolean hasMospExpressJar() {
		String expressVer = (String)ctx.getAttribute(MospConst.ATT_EXPRESS_VER);
		if (expressVer == null || expressVer.equals("")) {
			return false;
		}
		return true;
	}
	
	/**
	 * 初期コマンド取得。<br>
	 * @param invalidProcSeq 処理シーケンス不正時フラグ
	 * @return 初期コマンド
	 */
	@SuppressWarnings("unused")
	protected String getIndexCommand(boolean invalidProcSeq) {
		return MospConst.CMD_INDEX;
	}

	/**
	 * レスポンスヘッダー要否設定。<br>
	 * @param needHeader レスポンスヘッダー要否
	 */
	protected void setNeedHeader(boolean needHeader) { this.needHeader = needHeader; }
	
	/**
	 * セッション要否設定。<br>
	 * @param needSession セッション要否
	 */
	protected void setNeedSession(boolean needSession) { this.needSession = needSession; }
	
	/**
	 * ASPユーザー要否設定。<br>
	 * @param needAspUser ASPユーザー要否
	 */
	protected void setNeedAspUser(boolean needAspUser) { this.needAspUser = needAspUser; }
	
	/**
	 * ユーザー要否設定。<br>
	 * @param needUser ユーザー要否
	 */
	protected void setNeedUser(boolean needUser) { this.needUser = needUser; }
	
	/**
	 * 処理シーケンス確認要否設定。<br>
	 * @param checkProcSeq 処理シーケンス確認要否
	 */
	protected void setCheckProcSeq(boolean checkProcSeq) { this.checkProcSeq = checkProcSeq; }
	
	/**
	 * 処理シーケンス発行要否設定。<br>
	 * @param needProcSeq 処理シーケンス発行要否
	 */
	protected void setNeedProcSeq(boolean needProcSeq) { this.needProcSeq = needProcSeq; }
	
	/**
	 * 権限確認要否設定。<br>
	 * @param checkAuth 権限確認要否
	 */
	protected void setCheckAuth(boolean checkAuth) { this.checkAuth = checkAuth; }
	
	/**
	 * アプリケーションを設定する。<br>
	 * @param application アプリケーション
	 */
	protected void setApplication(String application) { this.application = application; }
	
	/**
	 * コントローラー設定(/WEB-INF/controller.properties)を設定する。<br>
	 * @param ctl コントローラー設定
	 */
	public void setCtl(Properties ctl) { this.ctl = ctl; }
	
	/**
	 * MosPアプリケーション設定(/WEB-INF/mosp.properties)を設定する。<br>
	 * @param cfg MosPアプリケーション設定
	 */
	public void setCfg(Properties cfg) { this.cfg = cfg; }
	
	/**
	 * メッセージ設定(/WEB-INF/message.properties)を設定する。<br>
	 * @param msg メッセージ設定
	 */
	public void setMsg(Properties msg) { this.msg = msg; }
	
	/**
	 * ASPユーザーを設定する。
	 * @param aspUser ASPユーザー
	 */
	public void setAspUser(CmAspUserDto aspUser) { this.aspUser = aspUser; }
	
	/**
	 * ユーザーを設定する。
	 * @param user ユーザー
	 */
	public void setUser(CmUserDto user) { this.user = user; }
	
	/**
	 * Cpmmandを設定する。
	 * @param cmd Command
	 */
	public void setCmd(String cmd) { this.cmd = cmd; }
	
	/**
	 * Voを設定する。<br>
	 * ここで設定したVoは、{@link #doAction()}でrequestに設定され、
	 * View(JSP等)で利用することができる。<br>
	 * @param vo Vo
	 */
	public void setVo(VoInterface vo) { this.vo = vo; }
	
	/**
	 * Voを取得する。<br>
	 * @return Vo
	 */
	public VoInterface getVo() { return vo; }
	
	/**
	 * フォワード先URLを設定する。<br>
	 * ここで設定したURLは、{@link #doAction()}でrequestに設定され、
	 * Controllerによりフォワードされる。<br>
	 * @param url フォワード先URL
	 */
	public void setUrl(String url) { this.url = url; }
	
	/**
	 * フォワード先URLを取得する。<br>
	 * @return フォワード先URL
	 */
	public String getUrl() { return url; }
	
	/**
	 * 連続実行Commandを設定する。<br>
	 * ここで設定したCommandは、{@link #doAction()}でrequestに設定され、
	 * Controllerにより、レスポンスを返すことなく実行される。<br>
	 * 連続実行Commandを設定した場合、Vo及びフォワード先URLの設定は
	 * 無効になる。<br>
	 * @param nextCmd 連続実行Command
	 */
	public void setNextCmd(String nextCmd) { this.nextCmd = nextCmd; }
	
	/**
	 * 連続実行Commandを取得する。<br>
	 * @return 連続実行Command
	 */
	public String getNextCmd() { return nextCmd; }
	
}
