/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JCKPmpApiReqchk
*   ソースファイル名：JCKPmpApiReqchk.java
*   作成者          ：富士通
*   日付            ：2011年07月01日
*＜機能概要＞
*   AxMに対して会員情報更新依頼を行います。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2011/07/01   FJ）眞方    新規作成
*
**********************************************************************/
package com.fujitsu.futurity.bp.custom.reqchk;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fujitsu.futurity.bp.x21.bpm.common.AbstractCustomReqChk;
import com.fujitsu.futurity.bp.x21.bpm.common.IConditionValue;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadOnly;
import com.fujitsu.futurity.bp.x21.bpm.reqchk.exception.ReqChkException;

/**
 * PMP連携サービスにおいて、SCへの入力パラメータや直前に実行されたSCの実行結果から次のSCの実行判定を行う。
 * 
 * @author 富士通
 */
public class JCKPmpApiReqchk extends AbstractCustomReqChk {

	/**
	 * 入力パラメータ、及び 直前のSCの実行結果から次のSCの実行判定を行う。
	 * @param 
	 * @param 
	 */
	@Override
	public boolean checkExecution(IRequestParameterReadOnly irp, IConditionValue conditionvalue) throws ReqChkException
	{

		// 判定モード、判定対象のパラメータ名の取得
		String[] conditionvalueAry = conditionvalue.get("value").split(",");
		String mode  = conditionvalueAry[0];
		String valStr = conditionvalueAry[1];
		String[] valKeyNames = new String[]{};
		String[] expKeyNames = new String[]{};
		if (("equals".equals(mode))||("notEquals".equals(mode))) {
			String[] valAry = valStr.split("=");
			valStr = valAry[0];
			expKeyNames = getColNames(valAry[1]);
		}
		valKeyNames = getColNames(valStr);

		// 対象SCのデータを取得(判定値用)
		Object objVal = null;
		try {
			String baseKey1 = valKeyNames[0];
			objVal = irp.getData(baseKey1);
		} catch (Exception e) {
		}

		// 対象SCのデータを取得(期待値用)
		Object expVal = null;
		try {
			String baseKey2 = expKeyNames[0];
			expVal = irp.getData(baseKey2);
		} catch (Exception e) {
		}

		// 対象SCのデータそのものがない時はダミーを設定
		if ((objVal == null)||(!(objVal instanceof Map))) {
			try {
				objVal = irp.getMappingWorkArea();
			} catch (Exception e) {
			}
			objVal = (objVal == null) ? new HashMap<String, Object>() : objVal;
		}

		// 対象SCのデータそのものがない時はダミーを設定
		if ((expVal == null)||(!(expVal instanceof Map))) {
			try {
				expVal = irp.getMappingWorkArea();
			} catch (Exception e) {
			}
			expVal = (expVal == null) ? new HashMap<String, Object>() : expVal;
		}

		// 期待値の取得( equals, notEqualsの時)
		for (int i = 1; i < (expKeyNames.length); i++) {
			String nextKey = expKeyNames[i];
			if (expVal != null) {
				if (expVal instanceof Map){
					Map objMap = (Map)expVal;
					expVal = objMap.get(nextKey);
				} else if (expVal instanceof List) {
					List objList = (List)expVal;
					expVal = objList.get(Integer.parseInt(nextKey));
				} else {
					expVal = null;
				}
			}
		}

		// 期待値のキー名がマップにない時は期待値のキー名をそのまま値として使用する
		if (expKeyNames.length == 1) {
			Map objMap = (Map)objVal;
			if (!objMap.containsKey(expKeyNames[0])) {
				expVal = expKeyNames[0];
			}
		}

		// 判定対象データの取得
		for (int i = 1; i < (valKeyNames.length); i++) {
			String nextKey = valKeyNames[i];
			if (objVal != null) {
				if (objVal instanceof Map){
					Map objMap = (Map)objVal;
					objVal = objMap.get(nextKey);
				} else if (objVal instanceof List) {
					List objList = (List)objVal;
					objVal = objList.get(Integer.parseInt(nextKey));
				} else {
					objVal = null;
				}
			}
		}

		/*
		 * 値の判定(「空でない事」が条件の時)
		 */
		if ("notEmpty".equals(mode)) {
			if (objVal == null) {
				return false;
			} else if (objVal instanceof String) {
				String objStr = (String)objVal;
				return (!"".equals(objStr));
			} else if (objVal instanceof Map) {
				Map objMap = (Map)objVal;
				return (!objMap.isEmpty());
			} else if (objVal instanceof List) {
				List objList = (List)objVal;
				return (!objList.isEmpty());
			}
		}

		/*
		 * 値の判定(「同じである事」が条件の時)
		 */
		if ("equals".equals(mode)) {
			if (objVal == null) {
				return ("null".equals(expVal));
			} else if (objVal instanceof String) {
				String objStr = (String)objVal;
				return (expVal.equals(objStr));
			} else if (objVal instanceof Integer) {
				Integer objInt = (Integer)objVal;
				return (objInt.compareTo(new Integer(expVal.toString())) == 0);
			} else if (objVal instanceof Long) {
				Long objLong = (Long)objVal;
				return (objLong.compareTo(new Long(expVal.toString())) == 0);
			} else if (objVal instanceof Boolean) {
				Boolean objBoolean = (Boolean)objVal;
				return (expVal.equals(objBoolean.toString()));
			} else {
				return false;
			}
		}

		/*
		 * 値の判定(「同じでない事」が条件の時)
		 */
		if ("notEquals".equals(mode)) {
			if (objVal == null) {
				return (!"null".equals(expVal));
			} else if (objVal instanceof String) {
				String objStr = (String)objVal;
				return (!expVal.equals(objStr));
			} else if (objVal instanceof Integer) {
				Integer objInt = (Integer)objVal;
				return (objInt.compareTo(new Integer(expVal.toString())) != 0);
			} else if (objVal instanceof Long) {
				Long objLong = (Long)objVal;
				return (objLong.compareTo(new Long(expVal.toString())) != 0);
			} else if (objVal instanceof Boolean) {
				Boolean objBoolean = (Boolean)objVal;
				return (!expVal.equals(objBoolean.toString()));
			} else {
				return false;
			}
		}

		return false;
	}

	private String[] getColNames(String str){

		List<String> keyNameList = new ArrayList<String>();
		String[] tmpKeyNames = str.split("\\.");
		for (int i = 0; i < tmpKeyNames.length; i++) {
			String keyName = tmpKeyNames[i];
			if (keyName.matches(".+\\[[0-9]+\\]$")) {
				String listName = keyName.replaceAll("\\[[0-9]+\\]", "");
				String indexStr = keyName.replace(listName, "").replaceAll("(\\[|\\])", "");;
				keyNameList.add(listName);
				keyNameList.add(indexStr);
			} else {
				keyNameList.add(keyName);
			}
		}

		String[] keyNames = new String[keyNameList.size()];
		for (int i = 0; i < keyNameList.size(); i++) {
			keyNames[i] = keyNameList.get(i);
		}

		return keyNames;
	}
}
