//===========================================================================
// package
//===========================================================================
package jp.gr.java_conf.bugslife.util;

//===========================================================================
// import
//===========================================================================
import java.io.*; 
import java.util.*;
import java.text.*; 
import java.text.ParseException; 

import java.util.regex.*; 

import org.apache.commons.logging.*;
import org.apache.struts.action.*;
import org.apache.struts.util.*;

//import jp.gr.java_conf.bugslife.system.*;

/**
 *<PRE>
 * Varidaterクラス
 *
 *
 *</PRE>
 * @version	0.0, 2001/01/04
 * @author	鰐川 正寛
 */
//===========================================================================
// version	0.0, 2001/01/04	新規作成
//===========================================================================
public class Varidater
{
//===========================================================================
// attributes
//===========================================================================
	/**
	 * message resources
	 */
	private static MessageResources m_messages =
	MessageResources.getMessageResources("ApplicationResources");
	/**
	 * エラーメッセージ定義
	 */
	public static final String REQUIRED_MSG = "varid.required";
	public static final String SELECTED_MSG = "varid.selected";
	public static final String INVALID_TYPE_MSG = "varid.invalid_type";
	public static final String INVALID_MAIL_MSG = "varid.invalid_mail";
	public static final String SIZE_LESS_MSG = "varid.size_less";
	public static final String SIZE_OVER_MSG = "varid.size_over";
	public static final String NOT_NUMERIC_MSG = "varid.not_numeric";
	public static final String NOT_SPACE_MSG = "varid.not_space";
	public static final String NOT_SPACE_OR_NUMERIC_MSG = "varid.not_space_or_numeric";
	public static final String INVALID_DATE_MSG = "varid.invalid_date";
	public static final String INVALID_DATA_MSG = "varid.invalid_data";
	public static final String GREATER_ERR_MSG = "varid.greater_err";
	public static final String NOT_ALPHANUMERIC_MSG = "varid.not_alphanumeric";
	
	public static final String NOT_SAME_MSG = "varid.not_same";
	/**
	 * ログ
	 */ 
	private static Log log = LogFactory.getLog(Varidater.class.getName());
//===========================================================================
// methods
//===========================================================================
//===========================================================================
// check methods
//===========================================================================
	/**
	 * 存在チェック
	 *
	 * @param o			値オブジェクト
	 * @param name		項目名
	 * @param errors	エラーオブジェクト
	 * @return 結果(true:存在 false:非存在)
	 */ 
	public static boolean checkRequired(Object o, String name, ActionErrors errors)
	{
		if (! isInput(o)) {
			addErrors(REQUIRED_MSG, name, errors);			//エラー追加
			return false;
		}
		return true;
	}
	/**
	 * 存在チェック(選択肢)
	 *
	 * @param o			値オブジェクト
	 * @param name		項目名
	 * @param errors	エラーオブジェクト
	 * @return 結果(true:存在 false:非存在)
	 */ 
	public static boolean checkSelected(Object o, String name, ActionErrors errors)
	{
		if (! isInput(o)) {
			addErrors(SELECTED_MSG, name, errors);			//エラー追加
			return false;
		}
		return true;
	}
	/**
	 * 存在チェック(コード系)
	 *
	 * @param o			値オブジェクト
	 * @param name		項目名
	 * @param types		デフォルト値配列
	 * @param errors	エラーオブジェクト
	 * @return 結果(true:OK false:NG)
	 */ 
	public static boolean checkRequiredCode(Object o, String name, String[] types, ActionErrors errors)
	{
		boolean ret = true;
		if (isInput(o)) {
			String val = o.toString();
			boolean match = false;
			for (int i = 0; i < types.length; i++) {
				if (val.equals(types[i])) {
					match = true;				//デフォルト値に一致
					break;
				}
			}
			if (match) {
				addErrors(REQUIRED_MSG, name, errors);	//エラー追加
				ret = false;
			}
		} else {
			addErrors(REQUIRED_MSG, name, errors);	//エラー追加
			ret = false;
		}
		
		return ret;
	}
	/**
	 * タイプのチェック
	 *
	 * @param o			値オブジェクト
	 * @param name		項目名
	 * @param types		取りうる値配列
	 * @param errors	エラーオブジェクト
	 * @return 結果(true:OK false:NG)
	 */ 
	public static boolean checkType(Object o, String name, String[] types, ActionErrors errors)
	{
		boolean ret = true;
		if (isInput(o)) {
			String val = o.toString();
			boolean match = false;
			for (int i = 0; i < types.length; i++) {
				if (val.equals(types[i])) {
					match = true;							//OK
					break;
				}
			}
			if (!match) {
				addErrors(INVALID_TYPE_MSG, name, errors);	//エラー追加
				ret = false;
			}
		}
		return ret;
	}
	/**
	 * 数値チェック
	 *
	 * @param o			値オブジェクト
	 * @param name		項目名
	 * @param errors	エラーオブジェクト
	 * @return 結果(true:OK false:NG)
	 */ 
	public static boolean checkNumeric(Object o, String name, ActionErrors errors)
	{
		String numericPattan = "^(\\d)+$";
		boolean ret = true;
		if (isInput(o)) {
			String val = o.toString();
			Pattern p = Pattern.compile(numericPattan);
			Matcher reg = p.matcher(val);
			if (! reg.find()) {
				addErrors(NOT_NUMERIC_MSG, name, errors);	//エラー追加
				ret = false;
			}
			
		}
		return ret;
	}
	/**
	 * メールアドレス妥当性チェック
	 *
	 * @param o			値オブジェクト
	 * @param name		項目名
	 * @param errors	エラーオブジェクト
	 * @return 結果(true:OK false:NG)
	 */ 
	public static boolean checkEmail(Object o, String name, ActionErrors errors)
	{
		String mailPattan = "^(\\w)+@(\\w)+";
		boolean ret = true;
		if (isInput(o)) {
			String val = o.toString();
			Pattern p = Pattern.compile(mailPattan);
			Matcher reg = p.matcher(val);
			if (! reg.find()) {
				addErrors(INVALID_MAIL_MSG, name, errors);	//エラー追加
				ret = false;
			}
			
		}
		return ret;
	}
	/**
	 * 日付妥当性チェック
	 *
	 * @param o			値オブジェクト
	 * @param name		項目名
	 * @param errors	エラーオブジェクト
	 * @return 結果(true:OK false:NG)
	 */ 
	public static boolean checkDate(Object o, String name, String pattan, ActionErrors errors)
	{
		boolean ret = true;
		//parse
		if (isInput(o)) {
			Date date = parseDate(o, pattan);
			if (date == null) {
				
				addErrors(INVALID_DATE_MSG, name, errors);	//エラー追加
				ret = false;
				
			}
		}
		return ret;
	}
	/**
	 * 日付変換
	 *
	 * @param o			値オブジェクト
	 * @param name		項目名
	 * @param errors	エラーオブジェクト
	 * @return 結果(true:OK false:NG)
	 */ 
	public static Date parseDate(Object o, String pattan) 
	{
		
		Date date = null;
		
		if (isInput(o)) {
			String val = o.toString();
			
			DateFormat df = new SimpleDateFormat(pattan);
			df.setCalendar(Calendar.getInstance());
			try {
				//parse
				date = df.parse(val);
				
				String newDate = df.format(date);
				if (! val.equals(newDate)) {
					date = null;
				}
			} catch (ParseException e) {
				date = null;
			}
		}
		return date;
	}
	/**
	 * 同一チェック
	 *
	 * @param o1		値オブジェクト１
	 * @param o2		値オブジェクト２
	 * @param name1		項目名１
	 * @param name2		項目名２
	 * @param errors	エラーオブジェクト
	 * @return 結果(true:OK false:NG)
	 */ 
	public static boolean checkSame(Object o1, Object o2, String name1, String name2, ActionErrors errors)
	{
		boolean ret = true;
		//両方入力されているか？
		if ((isInput(o1)) && (isInput(o2))) {
			if (! o1.equals(o2)) {
				//
				addErrors(NOT_SAME_MSG, new String[] { name1, name2} , errors);	//エラー追加
				ret = false;
			}
		//どちらかしか入力されていないか？
		} else if ((isInput(o1)) || (isInput(o2))) {
			
			addErrors(NOT_SAME_MSG, new String[] { name1, name2} , errors);	//エラー追加
			ret = false;
		}
		return ret;
	}
//===========================================================================
// methods
//===========================================================================
	/**
	 * エラーの追加
	 */
	public static void addErrors(String msgId, String name, ActionErrors errors) {
		
		String s = m_messages.getMessage(name + ".displayname");
		//名前が取れなかった場合項目名を埋める
		if(s == null) {
			s = "(" + name + ")";
		}
		errors.add(name, new ActionError(msgId, s));
		
	}
	/**
	 * エラーの追加
	 */
	public static void addErrors(String msgId, String[] names, ActionErrors errors) {
		
		String[] s = new String[names.length];
		for (int i = 0; i < names.length; i++) {
			s[i] = m_messages.getMessage(names[i] + ".displayname");
			//名前が取れなかった場合項目名を埋める
			if(s[i] == null) {
				s[i] = "(" + names[i] + ")";
			}
		}
		errors.add(names[0], new ActionError(msgId, s));
		
	}
	/**
	 * メッセージの取得
	 */
	public static String getMessage(String msgId) {
		
		String s = m_messages.getMessage(msgId);
		//名前が取れなかった場合項目名を埋める
		if(s == null) {
			s = "(" + msgId + ")";
		}
		return s;
		
	}
//===========================================================================
// utirity methods
//===========================================================================
	/**
	 * 入力確認
	 *
	 * @param o			値オブジェクト
	 * @return 結果(true:入力 false:未入力)
	 */ 
	public static boolean isInput(Object o)
	{
		if (o == null) {
			return false;
		} else {
			String val = o.toString();
			if (val.length() == 0) {
				return false;
			}
		}
		return true;
	}
	/**
	 * タイプ確認
	 *
	 * @param o			値オブジェクト
	 * @return 結果(true:入力 false:未入力)
	 */ 
	public static boolean isType(Object o, String[] types)
	{
		boolean match = false;
		
		if (isInput(o)) {
			String val = o.toString();
			for (int i = 0; i < types.length; i++) {
				if (val.equals(types[i])) {
					match = true;
					break;
				}
			}
		}
		return match;
	}
	/**
	 * デバッグ文字出力
	 *
	 * @param s 出力文字列
	 */
	private static void debug(String s) {
		System.out.println("[Varidater]" + s);
	}
	/**
	 *	テストメイン
	 */ 
	public static void main(String[] args)
	{
		//テスト開始
		System.out.println("----------Checker class Unit Test start!");
		
		//
//		runUnitTest1();
		runUnitTest2();
	}
	/**
	 * checkTypeのテスト
	 */ 
	public static void runUnitTest1()
	{
		
		//テスト開始
		System.out.println("<checkType Test>");
		
		ActionErrors errors = new ActionErrors();
		
		//支払い区分
		String[] payDivision = 
		{"10","21","22","23","24","25","31","32","33","34","35","61","62","63","64","65","80"};
		
		//test1 正しいデータ
		
		if (! Varidater.checkType("10", "userName", payDivision, errors )) {
			System.out.println("test 1:NG");
		}
		
		//test2 エラーデータ1
		if (Varidater.checkType("11", "userName", payDivision, errors )) {
			System.out.println("test 2:NG");
		}
		
		//test3 エラーデータ2
		if (Varidater.checkType("１１", "userName", payDivision, errors )) {
			System.out.println("test 3:NG");
		}
		
		//test4 短いデータ
		if (Varidater.checkType("1", "userName", payDivision, errors)) {
			System.out.println("test 4:NG");
		}
		
		//test5 長いデータ
		if (Varidater.checkType("100", "userName", payDivision, errors )) {
			System.out.println("test 5:NG");
		}
		
		System.out.println("error count = " + errors.size());
		
	}
	/**
	 * parseDateのテスト
	 */ 
	public static void runUnitTest2()
	{
		
		//テスト開始
		System.out.println("<unit test2>");
		
		String mmdd = "06/30";
		
		Date  date = parseDate(mmdd, Converter.MMDD_PATTAN);
		
		System.out.println(Converter.getDateString(date));
		
		
	}
}
