package com.ftinc.si.assist.run;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.ftinc.si.assist.test.AssertRecord;
import com.ftinc.si.assist.test.FakeMethodRecord;
import com.ftinc.si.assist.test.JSONRecord;
import com.ftinc.si.assist.test.ObjectRecord;
import com.ftinc.si.assist.test.TestCaseRecord;
import com.ftinc.si.assist.test.TestCommandRecord;
import com.ftinc.si.assist.test.Tool;

//テスト用のDBアクセスを仲介する。
//テスト実行プロセスの内部でJDBCを直接使用すると、テスト対象のメソッド内でのDBアクセスと競合する可能性があるため、
//別プロセス経由で必要な情報を取得する。
public class DBMediator {
	public static Connection s_connect = null;
	private static Statement m_statement = null;
	private OutputStreamWriter m_out = null;
	private OutputStreamWriter m_err = null;
	private static long s_milisec_of_last_access;

	public DBMediator() {}

	//DBMediatorをFTでテストするためのコンストラクタ
	public DBMediator(String str, String uid, String pwd) {
		init(str, uid, pwd);
	}

	//execMain（このプロセスのメインループ）の最初に呼ばれる。
	private boolean init(String str, String uid, String pwd) {
		if (s_connect != null) {
			//第二コンストラクタ経由の場合、二度呼ばれることがある。
			return true;
		}

		Tool.child_mode = true;
		try {
			//結果を受け取る側もUTF-8で待っているので合わせる。
			m_out = new OutputStreamWriter(System.out, "UTF-8"); //$NON-NLS-1$
			m_err = new OutputStreamWriter(System.err, "UTF-8"); //$NON-NLS-1$

			s_connect = DriverManager.getConnection(str, uid, pwd);
			s_connect.setAutoCommit(false);
		} catch (SQLException | UnsupportedEncodingException e) {
			try {
				if (m_out != null) {
					m_out.write("<fatal>" + e.getMessage() + "</fatal>\n");
					m_out.flush();
				}
			} catch (IOException e1) {
			}
			return false;
		}
		try {
			if (s_connect == null) {
				if (m_out != null) {
					m_out.write("<fatal>failed to connect by " + str + "</fatal>\n");
					m_out.flush();
				}
				return false;
			}
			m_out.write("<result></result>\n");
			m_out.flush();
		} catch (IOException e) {
			if (m_out != null) {
				Tool.logIfDebug(null, "Connection failed @DBMediator#init.");
			}
			return false;
		}
		return true;
	}

	protected void destroy() {
		try {
			s_connect.close();
			m_out.write("<result></result>\n"); //$NON-NLS-1$
			m_out.flush();
			Thread.sleep(1000); //flush待ち
			m_out.close();
			m_err.close();
		} catch (SQLException | InterruptedException | IOException e) {
			printStack(e);
		}
		System.exit(0);
	}

	public void execMain(HashMap<String, Object> cmds) {
		String conn_str = "";
		if (cmds.containsKey("connectStr")) {
			conn_str = cmds.get("connectStr").toString(); //$NON-NLS-1$
		} else {
			try {
				//結果を受け取る側もUTF-8で待っているので合わせる。
				m_out = new OutputStreamWriter(System.out, "UTF-8"); //$NON-NLS-1$
				m_out.write("<fatal>failed to connect >> connectStr is null.</fatal>\n");
				m_out.flush();
				m_out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return;
		}
		String uid = "";
		if (cmds.containsKey("uid")) {
			uid = cmds.get("uid").toString(); //$NON-NLS-1$
		}
		String pwd = "";
		if (cmds.containsKey("pwd")) {
			pwd = cmds.get("pwd").toString(); //$NON-NLS-1$
		}

		SweepThread t_thread = null;

		if (cmds.containsKey("gc")) { //$NON-NLS-1$
			if (cmds.get("gc").toString().equals("true")) { //$NON-NLS-1$ //$NON-NLS-2$
				//通信が5分途絶したら、自動的に終了するスレッドを起動する。
				t_thread = new SweepThread();
				t_thread.start();
				s_milisec_of_last_access = System.currentTimeMillis();
			}
		}

		if (init(conn_str, uid, pwd)) {
			//親プロセスからの入力ストリーム
			BufferedReader istream;
			try {
				//送信側もUTF-8で統一している。
				//BufferedReaderだとreadlineしやすいため。
				istream = new BufferedReader(new InputStreamReader(System.in, "UTF-8")); //$NON-NLS-1$
			} catch (UnsupportedEncodingException e2) {
				printStack(e2);
				return;
			}

			while (s_connect != null) {
				try {
					Thread.sleep(10);//CPUを使いすぎないため???
				} catch (InterruptedException e1) {
					printStack(e1);
				}
				//コマンドを受信する。
				//falseは読み終わってもプロセスが終了していないことを意味する。
				String t_command = Tool.readResultFromStream(istream, false);

				if (t_command != null && t_command.length() > 0) {
					s_milisec_of_last_access = System.currentTimeMillis();

					final Pattern t_pat = Pattern.compile("^\\s*<(\\w+?)>([\\s\\S]*)</(\\w+?)>\\s*$"); //$NON-NLS-1$
					Matcher t_m = t_pat.matcher(t_command);

					if (t_m.find()) {
						String cmd1 = t_m.group(1);
						String sqls = t_m.group(2);
						String cmd2 = t_m.group(3);
						if (cmd1.equals(cmd2)) {
							//コマンド書式が正しい
							try {
								switch (cmd1) {
									case "destroy": destroy(); break; //$NON-NLS-1$
									case "commit": commit(); m_out.write("<result></result>\n"); break; //$NON-NLS-1$ //$NON-NLS-2$
									case "rollback": rollback(); m_out.write("<result></result>\n"); break; //$NON-NLS-1$ //$NON-NLS-2$
									case "updateBySQL": updateBySQL(sqls); m_out.write("<result></result>\n"); break;  //$NON-NLS-1$ //$NON-NLS-2$
									case "isReady": isReady(); break; //$NON-NLS-1$
									case "getJSONRecord": getJSONRecord(sqls); break; //$NON-NLS-1$
									case "getJSONRecWhere": getJSONRecWhere(sqls); break; //$NON-NLS-1$
									case "getAssert": getAssert(sqls); break; //$NON-NLS-1$
									case "getObjectRecord": getObjectRecord(sqls);break; //$NON-NLS-1$
									case "getReferringObjectList": getReferringObjectList(sqls); break; //$NON-NLS-1$
									case "getReusableObjectRecord": getReusableObjectRecord(sqls); break; //$NON-NLS-1$
									case "getMethodSource": getMethodSource(sqls); break; //$NON-NLS-1$
									case "getFakeMethods": getFakeMethods(sqls); break; //$NON-NLS-1$
									case "getAllFakes": getAllFakes(sqls); break; //$NON-NLS-1$
									case "getTestIDsByReturnType": getTestIDsByReturnType(sqls); break; //$NON-NLS-1$
									case "getNewTestCase": getNewTestCase(sqls); break; //$NON-NLS-1$
									case "getTestCaseList": getTestCaseList(sqls); break; //$NON-NLS-1$
									case "getReferringTestCaseList": getReferringTestCaseList(sqls); break; //$NON-NLS-1$
									case "getTestCmd": getTestCmd(sqls); break; //$NON-NLS-1$
									case "getTestCmdList": getTestCmdList(sqls); break; //$NON-NLS-1$
									case "getReferringTestCmdList": getReferringTestCmdList(sqls); break; //$NON-NLS-1$
									case "countCase": countCase(sqls); break; //$NON-NLS-1$
									case "createTable": createTable(); m_out.write("<result></result>\n"); break; //$NON-NLS-1$ //$NON-NLS-2$
									case "getCaseStatus": getCaseStatus(sqls); break; //$NON-NLS-1$
									case "selectBySQL": selectBySQL(sqls); break; //$NON-NLS-1$
									case "close": close(null); m_out.write("<result></result>\n"); break;//statementを閉じる。 //$NON-NLS-1$ //$NON-NLS-2$
									default: Tool.alertMSG(null, sqls + Messages.getString("DBMediator.42"));break; //$NON-NLS-1$
								}
								m_out.flush();

							} catch (Exception e) {
								printStack(e);
							} finally {
								//予期しない例外で抜けるのを防ぐ
							}
						}
					}
				} else {
					try {
						m_out.write("<result></result>\n");
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		} else {
			destroy();
		}
	}

	protected void write(OutputStreamWriter o, String str) {
		try {
			o.write(str + "\n"); //$NON-NLS-1$
		} catch (IOException e) {
			System.err.print("<error>"); //$NON-NLS-1$
			e.printStackTrace();
			System.err.print("</error>\n"); //$NON-NLS-1$
			System.err.flush();
		}
	}


	protected void printStack(Exception e) {
		try {
			m_err.write("<error>"); //$NON-NLS-1$
			m_err.flush();
			e.printStackTrace();
			m_err.write("</error>\n"); //$NON-NLS-1$
			m_err.flush();
		} catch (IOException e1) {
			System.err.print("<error>"); //$NON-NLS-1$
			e1.printStackTrace();
			System.err.print("</error>\n"); //$NON-NLS-1$
			System.err.flush();
		}
	}

	//テーブル定義が済かどうかを調べる。
	protected void isReady() {
		try {
			String t_sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";
			ResultSet t_res = select(t_sql);
			while (t_res.next()) {
				String t_name = t_res.getString("table_name");
				if ("tbl_TestCaseRecord".equals(t_name)) {
					write(m_out, "<result>true</result>"); //$NON-NLS-1$
					return;
				}
			}
			close(t_res);
		} catch (SQLException e) {
			write(m_out, "<error>" + e.getMessage() + "</error>"); //$NON-NLS-1$ //$NON-NLS-2$
			return;
		}
		write(m_out, "<result>false</result>"); //$NON-NLS-1$
	}


	private ResultSet select(String sql) throws SQLException {
		m_statement = s_connect.createStatement();
		return m_statement.executeQuery(sql);
	}

	//※case文、max、minなどの関数は使えない。制限事項である。
	protected void selectBySQL(String sql) {
		ArrayList<HashMap<String, String>> t_list = new ArrayList<HashMap<String, String>>();
		try {
			//Select文を解析して、返す必要のあるカラムを取得する。
			final Pattern t_pat = Pattern.compile("(?i)^select\\s+(.+)\\s+from"); //$NON-NLS-1$
			Matcher t_m = t_pat.matcher(sql);
			String colName = ""; //$NON-NLS-1$
			if (t_m.find()) {
				colName = t_m.group(1);
				if ("count(*)".equals(colName)) { //$NON-NLS-1$
					ResultSet t_res = select(sql);
					if (t_res.next()) {
						Integer n = t_res.getInt(1);
						HashMap<String, String> t_map = new HashMap<String, String>();
						t_map.put("count", n.toString()); //$NON-NLS-1$
						t_list.add(t_map);
					}
					close(t_res);
				} else {
					colName = colName.replace(" ", "");//空白をトル
					colName = colName.replace("\"", "");//"をトル

					String[] colNames = colName.split(","); //$NON-NLS-1$
					List<String> colList = Arrays.asList(colNames);

					ResultSet t_res = select(sql);
					ResultSetMetaData t_meta = t_res.getMetaData();
					while (t_res.next()) {
						HashMap<String, String> t_map = new HashMap<String, String>();
						for (int i = 0; i < t_meta.getColumnCount(); i ++) {
							String t_key = t_meta.getColumnName(i + 1);

							//必要なカラムだけ取得を試みる。
							if (colName.equals("*") || colList.contains(t_key) || colName.matches("^\\d+$")) { //$NON-NLS-1$
								t_map.put(t_key, t_res.getString(t_key));
							}
						}
						t_list.add(t_map);
					}
					close(t_res);
				}

				String t_result = Tool.getJSONfromObject(t_list);
				if (t_result == null) {
					t_result = ""; //$NON-NLS-1$
				}
				write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
			} else {
				write(m_out, "<error>" + Messages.getString("DBMediator.66")+  sql + "\"</error>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void close(ResultSet res) throws SQLException {
		if (res != null) {
			res.close();
		}
		if (m_statement != null) {
			m_statement.close();
			m_statement = null;
		}
	}

	protected void getJSONRecord(String sql) {
		try {
			ResultSet t_res = select(sql);

			JSONRecord t_rec = null;
			if (t_res.next()) {
				t_rec = new JSONRecord(0);
				t_rec.read(t_res);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_rec);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}


	protected void getJSONRecWhere(String sql) {
		try {
			ArrayList<JSONRecord> t_list = new ArrayList<JSONRecord>();

			ResultSet t_res = select(sql);

			while (t_res.next()) {
				JSONRecord t_rec = new JSONRecord(0);
				t_rec.read(t_res);
				t_list.add(t_rec);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_list);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getAssert(String sql) {
		try {
			ResultSet t_res = select(sql);
			AssertRecord t_rec = null;
			if (t_res.next()) {
				t_rec = new AssertRecord(0);
				t_rec.read(t_res);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_rec);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getObjectRecord(String sql) {
		try {
			ResultSet t_res = select(sql);
			ObjectRecord t_rec = null;
			if (t_res.next()) {
				t_rec = new ObjectRecord(0);
				t_rec.read(t_res);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_rec);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getReferringObjectList(String sql) {
		try {
			ArrayList<String> t_list = new ArrayList<String>();
			ResultSet t_res = select(sql);
			while ( t_res.next() ) {
				t_list.add(t_res.getString("ID")); //$NON-NLS-1$
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_list);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			Tool.alertMSG(null, e.getMessage());
		}
	}

	protected void getReusableObjectRecord(String sql) {
		try {
			ArrayList<ObjectRecord> t_list = new ArrayList<ObjectRecord>();

			ResultSet t_res = select(sql);

			while (t_res.next()) {
				ObjectRecord t_rec = new ObjectRecord(0);
				t_rec.read(t_res);

				t_list.add(t_rec);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_list);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getMethodSource(String sql) {
		try {
			ResultSet t_res = select(sql);
			FakeMethodRecord frd = new FakeMethodRecord(0);

			while ( t_res.next() ) {
				frd.read(t_res);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(frd);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getFakeMethods(String sql) {
		try {
			ArrayList<FakeMethodRecord> t_list = new ArrayList<FakeMethodRecord>();

			ResultSet t_res = select(sql);
			while ( t_res.next() ) {
				FakeMethodRecord frd = new FakeMethodRecord(0);
				frd.read(t_res);
				t_list.add(frd);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_list);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getAllFakes(String sql) {
		try {
			ArrayList<FakeMethodRecord> t_list = new ArrayList<FakeMethodRecord>();
			ResultSet t_res = select(sql);

			while ( t_res.next() ) {
				FakeMethodRecord frd = new FakeMethodRecord(0);
				frd.read(t_res);
				t_list.add(frd);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_list);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getTestIDsByReturnType(String sql) {
		ArrayList<String> t_list = new ArrayList<String>();

		try {
			ResultSet t_res = select(sql);
			while ( t_res.next() ) {
				t_list.add(t_res.getString("ID")); //$NON-NLS-1$
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_list);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getNewTestCase(String sql) {
		int n = 0;
		try {
			ResultSet t_res = select(sql);
			while ( t_res.next() ) {
				n = t_res.getInt("End"); //$NON-NLS-1$
			}
			close(t_res);

			TestCaseRecord t_rec = new TestCaseRecord(2); //新規
			t_rec.begin = n + 1;
			t_rec.end = n + TestCaseRecord.s_unitSize;
			t_rec.groupCode = Tool.group_code;
			t_rec.version = Tool.version;

			String t_result = Tool.getJSONfromObject(t_rec);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getTestCaseList(String sql) {
		ArrayList<TestCaseRecord> t_list = new ArrayList<TestCaseRecord>();

		TestCaseRecord t_rec = null;
		try {
			ResultSet t_res = select(sql);
			while ( t_res.next() ) {
				t_rec = new TestCaseRecord(0);
				t_rec.read(t_res);
				t_list.add(t_rec);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_list);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getReferringTestCaseList(String sql) {
		try {
			ArrayList<String> t_list = new ArrayList<String>();
			ResultSet t_res = select(sql);
			while ( t_res.next() ) {
				t_list.add(t_res.getString("Name")); //$NON-NLS-1$
			}
			close(t_res);

			String t_result = ""; //$NON-NLS-1$
			if (t_list.size() > 0) {
				t_result = Tool.getJSONfromObject(t_list);
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getTestCmd(String sql) {
		try {
			ResultSet t_res = select(sql);
			TestCommandRecord t_rec = new TestCommandRecord(0);
			while ( t_res.next() ) {
				t_rec.read(t_res);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_rec);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void getTestCmdList(String sql) {
		try {
			ArrayList<TestCommandRecord> t_list = new ArrayList<TestCommandRecord>();

			ResultSet t_res = select(sql);
			while ( t_res.next() ) {
				TestCommandRecord t_rec = new TestCommandRecord(0);
				t_rec.read(t_res);

				t_list.add(t_rec);
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_list);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}


	protected void getReferringTestCmdList(String sql) {
		try {
			ArrayList<String> t_list = new ArrayList<String>();
			ResultSet t_res = select(sql);
			while ( t_res.next() ) {
				t_list.add(t_res.getString("ID") + "@" + t_res.getString("TestCase")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
			close(t_res);

			String t_result = Tool.getJSONfromObject(t_list);
			if (t_result == null) {
				t_result = ""; //$NON-NLS-1$
			}
			write(m_out, "<result>" + t_result + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void countCase(String sql) {
		try {
			Integer result = Integer.valueOf(0);
			m_statement = s_connect.createStatement();

			ResultSet t_rs = m_statement.executeQuery(sql);
			if (t_rs.next()) {
				result = t_rs.getInt(1);
			}
			close(t_rs);

			write(m_out, "<result>" + result.toString() + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (SQLException e) {
			printStack(e);
		}
	}

	protected void createTable() {
		String err_msg = ""; //$NON-NLS-1$
		ArrayList<String> t_list = Tool.createTableSQL();
		if (t_list.size() > 0) {
			try {
				m_statement = s_connect.createStatement();
				for (int i = 0; i < t_list.size(); i++) {
					err_msg = t_list.get(i);
					m_statement.executeUpdate(t_list.get(i));
				}
				commit();

			} catch (SQLException e) {
				Tool.alertMSG(null, e.getMessage() + "\nSQL=\n" + err_msg); //$NON-NLS-1$
				try {
					rollback();
				} catch (SQLException e1) {
					//rollbackするまでもなかった。
					Tool.logIfDebug(e, "@DBMediator#createTable"); //$NON-NLS-1$
				}
			} finally {
				try {
					close(null);
				} catch (SQLException e) {
					Tool.logIfDebug(e, "@DBMediator#createTable"); //$NON-NLS-1$
				}
			}
		}
	}


	protected void updateBySQL(String str) throws SQLException {
		String[] t_args = str.split("\t"); //$NON-NLS-1$

		update(t_args[0], Boolean.valueOf(t_args[1]));
	}

	protected void update(String sql, boolean bCommit) throws SQLException {
		if (sql != null) {
			try {
				if (m_statement == null) {
					m_statement = s_connect.createStatement();
				}
				m_statement.execute(sql);

				if (bCommit) {
					s_connect.commit();
				}
			} catch (SQLException e) {
				if (bCommit) {
					s_connect.rollback();
				}
			} finally {
				if (bCommit) {
					m_statement.close();
					m_statement = null;
				}
			}
		}
	}

	protected void commit() throws SQLException {
		s_connect.commit();
	}

	protected void rollback() throws SQLException {
		s_connect.rollback();
	}

	protected void getCaseStatus(String json) {
		String t_result = ""; //$NON-NLS-1$
		String num_all = ""; //$NON-NLS-1$
		String num_incomp = ""; //$NON-NLS-1$

		@SuppressWarnings("unchecked")
		ArrayList<String> sqls = (ArrayList<String>)Tool.getObjectfromJSON(ArrayList.class, json);

		ResultSet t_rs;
		try {
			m_statement = s_connect.createStatement();

			t_rs = m_statement.executeQuery(sqls.get(0));
			if (t_rs.next()) {
				num_all = t_rs.getString(1);
			} else {
				num_all = "0"; //$NON-NLS-1$
			}
			t_rs.close();
		} catch (SQLException e) {
			printStack(e);
		}

		try {
			t_rs = m_statement.executeQuery(sqls.get(1));
			if (t_rs.next()) {
				num_incomp = t_rs.getString(1);
			} else {
				num_incomp = "0"; //$NON-NLS-1$
			}
			t_rs.close();
		} catch (SQLException e) {
			printStack(e);
		}
		t_result = "TestCommandRecord(incompleted/all) = " + num_incomp + " / " + num_all + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$


		try {
			t_rs = m_statement.executeQuery(sqls.get(2));
			if (t_rs.next()) {
				num_all = t_rs.getString(1);
			} else {
				num_all = "0"; //$NON-NLS-1$
			}
			t_rs.close();
		} catch (SQLException e) {
			printStack(e);
		}

		try {
			t_rs = m_statement.executeQuery(sqls.get(3));
			if (t_rs.next()) {
				num_incomp = t_rs.getString(1);
			} else {
				num_incomp = "0"; //$NON-NLS-1$
			}
			t_rs.close();
		} catch (SQLException e) {
			printStack(e);
		}
		t_result += "ObjectRecord(incompleted/all) = " + num_incomp + " / " + num_all + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		try {
			t_rs = m_statement.executeQuery(sqls.get(4));
			if (t_rs.next()) {
				num_all = t_rs.getString(1);
			} else {
				num_all = "0"; //$NON-NLS-1$
			}
			t_rs.close();
		} catch (SQLException e) {
			printStack(e);
		}

		try {
			t_rs = m_statement.executeQuery(sqls.get(5));
			if (t_rs.next()) {
				num_incomp = t_rs.getString(1);
			} else {
				num_incomp = "0"; //$NON-NLS-1$
			}
			t_rs.close();
		} catch (SQLException e) {
			printStack(e);
		}
		try {
			m_statement.close();
		} catch (SQLException e) {
			printStack(e);
		}

		t_result += "AssertRecord(incompleted/all) = " + num_incomp + " / " + num_all + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		write(m_out, "<result>" + Tool.getJSONfromObject(t_result) + "</result>"); //$NON-NLS-1$ //$NON-NLS-2$
	}


	//ゴミになっているか判断するスレッド。
	private class SweepThread extends Thread {
		public void run(){
			try {
				Thread.sleep(60000); //1分間隔で調べる

				if (System.currentTimeMillis() - s_milisec_of_last_access > 360000) {
					//最後の処理から、6分以上たったら終わる。
					Tool.destroy();
					System.exit(0);
				}
			}catch(InterruptedException e){
			}
		}
	}
}
