package com.ftinc.si.assist.test.gui;

import java.awt.Component;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.im.InputContext;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.text.Caret;

import com.ftinc.si.assist.run.Messages;
import com.ftinc.si.assist.test.FakeMethodRecord;
import com.ftinc.si.assist.test.Fson;
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.Tool;

public class ArgumentEditor extends JDialog {
	public static TestCaseEditor s_owner;

	private JTextField textTestID;
	private JTextField textCName;
	private JComboBox<String> stackBox;
	private JTextArea textJSON;
	private JButton btnCreateFake;

	ObjectRecord m_original;
	public ObjectRecord m_work;
	private String m_stack0;//元々の引数のスタック。$nのこと。元に戻せるように記憶。
	boolean is_pojo = false;

	//icaseはincludeしたTestCase、stack0は、引数の位置。$n形式で来る。
	public ArgumentEditor(TestCaseEditor owner, ObjectRecord rec, String stack0) {
		super(owner, true);
		setResizable(false);

		m_original = rec;
		m_work = rec._dup(true);//作業用の複製。trueはstatusまでコピー
		m_stack0 = stack0;
		is_pojo = rec.isPOJO;

		setTitle(Messages.getString("ArgumentEditor.0")); //$NON-NLS-1$
		getContentPane().setLayout(null);
		setBounds(120, 120, 620, 526);

		JLabel lblTestid = new JLabel(Messages.getString("ArgumentEditor.1")); //$NON-NLS-1$
		lblTestid.setBounds(12, 10, 50, 13);
		getContentPane().add(lblTestid);

		textTestID = new JTextField();
		textTestID.setEditable(false);
		textTestID.setBounds(81, 7, 120, 19);
		getContentPane().add(textTestID);
		textTestID.setColumns(10);
		textTestID.setText(Integer.valueOf(rec.testID).toString());

		JLabel lblClassname = new JLabel(Messages.getString("ArgumentEditor.2")); //$NON-NLS-1$
		lblClassname.setBounds(12, 43, 66, 13);
		getContentPane().add(lblClassname);

		textCName = new JTextField();
		textCName.setBounds(12, 66, 285, 19);
		getContentPane().add(textCName);
		textCName.setColumns(10);
		textCName.setText(rec.className);

		JLabel lblStack = new JLabel(Messages.getString("ArgumentEditor.3")); //$NON-NLS-1$
		lblStack.setHorizontalAlignment(SwingConstants.LEFT);
		lblStack.setBounds(309, 43, 75, 13);
		getContentPane().add(lblStack);

		JCheckBox notFake = new JCheckBox(Messages.getString("ArgumentEditor.4")); //$NON-NLS-1$
		notFake.setEnabled(true);
		notFake.setSelected(is_pojo);

		notFake.setBounds(309, 6, 135, 21);
		getContentPane().add(notFake);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(12, 141, 586, 325);
		getContentPane().add(scrollPane);

		textJSON = new JTextArea();
		textJSON.addMouseWheelListener(new MouseWheelListener() {
			public void mouseWheelMoved(MouseWheelEvent e) {
				//マウスホイールの操作により、フォントサイズを変える。
				Font t_font = Tool.resizeFont(e, textJSON.getFont());
				if (t_font != null) {
					textJSON.setFont(t_font);
				}
			}
		});
		textJSON.setFont(new Font("MS UI Gothic", Font.PLAIN, 14));
		scrollPane.setViewportView(textJSON);
		textJSON.setText(rec.jSON);
		textJSON.enableInputMethods(false);
		textJSON.setEditable(!TestCaseEditor.unableMode);
		InputContext ic = textJSON.getInputContext();
		ic.setCompositionEnabled(true);

		//同じクラス名を持つJSONテンプレートからひな形を取得する。
		final JButton btnFindTemplate = new JButton(Messages.getString("ArgumentEditor.5")); //$NON-NLS-1$
		btnFindTemplate.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (!btnFindTemplate.isEnabled()) {
					return;
				}

				if (!textJSON.getText().equals(m_work.jSON)) {
					m_work.jSON = textJSON.getText();
					m_work.changed();
				}
				if (!insertByJSONChooser()) {
					//部分置き換えの対象であれば、if文の中で実行済み。
					//以下は、JSONChooserで選択した文字列を丸々置き換える場合。

					ArrayList<JSONRecord> t_data = Tool._db().getJSONRecWhere(m_work.className, null, Tool.version);
					if (t_data.size() > 0) {
						JSONChooser chooser = new JSONChooser((JDialog)Tool.getParent((Component)e.getSource(), "JDialog"), t_data); //$NON-NLS-1$
						chooser.setVisible(true);
						if (chooser.is_ok) {
							textJSON.setText(chooser.m_json);
							m_work.setJSON(chooser.m_json);
						}
					} else {
						Tool.alertMSG(null, Messages.getString("ArgumentEditor.11")); //$NON-NLS-1$
					}
				}
			}
		});
		btnFindTemplate.setBounds(346, 103, 120, 21);
		btnFindTemplate.setEnabled(!TestCaseEditor.unableMode);
		getContentPane().add(btnFindTemplate);

		stackBox = new JComboBox<String>();
		stackBox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				//上下のクラスが選択されたら
				Object t_obj = stackBox.getSelectedItem();
				if (t_obj != null) {
					String t_strid = t_obj.toString();
					if (isSnapshot(t_strid)) {
						Tool.alertMSG(null, "SnapshotCommand can not be specified.");
						stackBox.setSelectedItem(null);
					} else {
						m_work.stack = t_strid;
					}
				}
			}
		});
		stackBox.setEditable(true);

		stackBox.setBounds(309, 67, 289, 16);
		getContentPane().add(stackBox);

		JLabel lblJson = new JLabel(Messages.getString("ArgumentEditor.6")); //$NON-NLS-1$
		lblJson.setBounds(12, 107, 50, 13);
		getContentPane().add(lblJson);

		final JButton btnOK = new JButton(Messages.getString("ArgumentEditor.7")); //$NON-NLS-1$

		//OK
		btnOK.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (!btnOK.isEnabled()) {
					return;
				}

				//t_recのクラス名が再定義されていた場合、それが適正かどうかチェック。
				//不適切なら元に戻る。
				if (!m_work.className.equals(m_original.typeName)) {
					//型が変更されていれば、適正かチェックする。
					Class<?> o_class;
					try {
						o_class = Tool.forName(m_original.typeName);
					} catch (ClassNotFoundException e1) {
						Tool.alertMSG(null, Messages.getString("ArgumentEditor.13") + m_original.typeName); //$NON-NLS-1$
						return;
					}
					Class<?> e_class;
					try {
						e_class = Tool.forName(m_work.className);
					} catch (ClassNotFoundException e1) {
						Tool.alertMSG(null, Messages.getString("ArgumentEditor.14") + m_work.className); //$NON-NLS-1$
						return;
					}
					if (!o_class.isAssignableFrom(e_class)) {
						Tool.alertMSG(null, Messages.getString("ArgumentEditor.15") + m_work.className + Messages.getString("ArgumentEditor.16") + m_original.typeName); //$NON-NLS-1$ //$NON-NLS-2$
						return;
					}
				}

				if (!textJSON.getText().equals(m_work.jSON)) {
					m_work.setJSON(textJSON.getText());
				}
				if (m_work.jSON.equals(Messages.getString("ArgumentEditor.17"))) { //$NON-NLS-1$
					//明にnull指定の場合、完成とする。
					m_work.completed = true;
				} else if (m_work.jSON.length() > 0) {
					try {
						//fakeの場合、jsonはVarDictionaryの更新に使われる。
						String cname = m_work.className;
						if (!is_pojo) {
							cname = "java.util.HashMap"; //$NON-NLS-1$
						}
						Class<?> t_c = null;
						if (!cname.equals("java.lang.Class")) {
							t_c = Tool.forName(Tool.primitiveToFQN(cname));
						}

						Object t_obj = Tool.getObjectfromJSON(t_c, m_work.jSON);
						if (t_obj == null && (m_work.jSON.length() > 0 && !m_work.jSON.equals("null"))) {
							//JSONがあるのにオブジェクトが構成できない。
							m_work.completed = false;
							return; //間違いがあるので閉じない。
						} else if (is_pojo && t_obj != null) {
							m_work.completed = false;

							//オブジェクトが再構成できて、jsonの中のfieldが実在するかチェック。すべて実在すれば完成と判断。
							if (t_c == null) {
								//クラスがなくても無事生成。t_c=Class<?>などの場合。
								m_work.completed = true;
							} else if (checkJSONField(Tool.forName(Tool.primitiveToFQN(m_work.className)), m_work.jSON)) {
								m_work.completed = true;
							}
						} else {
							m_work.completed = true;
						}
					} catch (ClassNotFoundException e1) {
						Tool.alertMSG(null, e1.getMessage());
					}
				} else {
					//スタック欄に再利用Objectが指定されていたら完成とみなす。
					Object t_obj = stackBox.getSelectedItem();
					if (t_obj != null) {
						String t_strid = t_obj.toString();
						if (t_strid.matches("^[0-9]+\\$[_0-9]+[\\w\\(\\)\\.]*$")) {
							m_work.completed = true;
						}
					}
				}

				if (!m_work.equals(m_original)) {
					m_original.isPOJO = m_work.isPOJO;
					m_original.completed = m_work.completed;
					m_original.jSON = m_work.jSON; //stackが既存オブジェクトの場合、更新する。そうでないなら新規に作る。
					m_original.className = m_work.className;
					m_original.removed = m_work.removed;
					m_original.stack = m_work.stack;
					m_original.enable = m_work.enable;
					m_original.changed();
				}

				setVisible(false);
			}
		});
		btnOK.setBounds(186, 470, 91, 21);
		btnOK.setEnabled(!TestCaseEditor.unableMode);
		getContentPane().add(btnOK);

		final JButton btnAddTemplate = new JButton(Messages.getString("ArgumentEditor.8")); //$NON-NLS-1$
		//JSONテンプレートの登録。
		btnAddTemplate.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (!btnAddTemplate.isEnabled()) {
					return;
				}

				//通常のJSONのみテンプレートにできる。
				if (!m_work.jSON.matches("^\\s*\\([\\w\\.]+\\)\\$1=.*$")) { //$NON-NLS-1$
					//新IDの取得
					String t_val = JOptionPane.showInputDialog(this, Messages.getString("ArgumentEditor.19") + m_work.className + Messages.getString("ArgumentEditor.20")); //$NON-NLS-1$ //$NON-NLS-2$
					if (t_val != null){
						if (Tool._db().getJSONRecord(m_work.className, t_val, Tool.version) != null) {
							saveJson(t_val, true);
						} else {
							saveJson(t_val, false);
						}
					}
				} else {
					Tool.alertMSG(null, Messages.getString("ArgumentEditor.21")); //$NON-NLS-1$
				}
			}
		});
		btnAddTemplate.setBounds(478, 103, 120, 21);
		btnAddTemplate.setEnabled(!TestCaseEditor.unableMode);
		getContentPane().add(btnAddTemplate);

		btnCreateFake = new JButton(Messages.getString("ArgumentEditor.9")); //$NON-NLS-1$
		btnCreateFake.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (!btnCreateFake.isEnabled()) {
					return;
				}
				String cname = textCName.getText();

				MethodEditor t_br = new MethodEditor(null, cname, null, null, null);

				t_br.setBounds(e.getXOnScreen() - 200, e.getYOnScreen(), t_br.getWidth(), t_br.getHeight());
				t_br.setVisible(true);

				FakeMethodRecord t_rec = t_br.getFakeMethodRecord();
				if (t_rec != null) {
					try {
						if (Tool.existClass(t_rec.className)) {
							Tool._db().updateRecordBySQL(t_rec.getUpdateSQL(), true);
						} else {
							//Fakeを作る。
							Tool._db().updateRecordBySQL(t_rec.getUpdateSQL(), true);
							Tool.getFakeInstance(cname);
						}
					} catch (SQLException e1) {
						Tool.alertMSG(null, Messages.getString("ArgumentEditor.12") + e1.getMessage()); //$NON-NLS-1$
					}
				}
			}
		});
		btnCreateFake.setBounds(478, 6, 120, 21);
		btnCreateFake.setEnabled(false);
		getContentPane().add(btnCreateFake);

		notFake.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				is_pojo = !is_pojo;		//反転する。
				m_work.isPOJO = is_pojo;
				m_work.changed();

				if (!TestCaseEditor.unableMode) {
					if (is_pojo) {
						btnCreateFake.setEnabled(false);
						stackBox.setEnabled(true);
					} else {
						stackBox.setEnabled(false);
						btnCreateFake.setEnabled(true);
					}
				}
			}
		});
		notFake.setSelected(rec.isPOJO);

		JButton btnCancel = new JButton(Messages.getString("ArgumentEditor.btnCancel.text")); //$NON-NLS-1$
		btnCancel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				setVisible(false);
			}
		});
		btnCancel.setBounds(289, 470, 91, 21);
		getContentPane().add(btnCancel);

		//JSONEditorを起動し、生成物をテキストエリアに転記する。
		final JButton editJson = new JButton(Messages.getString("ArgumentEditor.22")); //$NON-NLS-1$
		editJson.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (!editJson.isEnabled()) {
					return;
				}
				String cname = textCName.getText();
				if (!is_pojo) {
					cname = "java.util.HashMap";
				}
				JSONEditor t_ed = new JSONEditor(null, cname, "", textJSON.getText()); //$NON-NLS-1$
				t_ed.setVisible(true);
				if (!textJSON.getText().equals(t_ed.getJson())) {
					textJSON.setText(t_ed.getJson());
				}
			}
		});
		editJson.setBounds(57, 103, 120, 21);
		editJson.setEnabled(!TestCaseEditor.unableMode);
		getContentPane().add(editJson);

		final JButton btnDefalutJson = new JButton(Messages.getString("ArgumentEditor.btnDefalutJson.text")); //$NON-NLS-1$
		btnDefalutJson.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (!btnDefalutJson.isEnabled()) {
					return;
				}

				//各フィールドのJSONの定型式を書く。
				String t_cname = textCName.getText();

				String str_j = Tool.classToJSON(t_cname);
				if (str_j != null) {
					textJSON.setText(str_j);
				}
			}
		});
		btnDefalutJson.setBounds(186, 103, 111, 21);
		btnDefalutJson.setEnabled(!TestCaseEditor.unableMode);
		getContentPane().add(btnDefalutJson);

		// 再利用できるインスタンス（テスト実行によって生成されるもののうち同じクラス名であるもの）候補を登録する。
		initStack();
	}

	private void initStack() {
		//同一のTestCaseの中で、stackの候補を検索する。但し、選択候補になるのはDBに格納済みのものだけ。後は手入力。
		//参照されているリストおよび全候補リストを作る。
		//全候補リストのうち、参照されているもの（最新ではない）を除いて、comboに登録する。
		ArrayList<String> refered = new ArrayList<String>();
		ArrayList<String> reusables = new ArrayList<String>();

		ArrayList<TestCaseRecord> case_list = Tool._db().getTestCaseList(m_work.testCase, 0, 0, "", Tool.version);
		if (case_list.size() > 0) {
			TestCaseRecord t_rec = case_list.get(0);

			//返却値の型が同じクラスの場合
			ArrayList<String> testIDs = Tool._db().getTestIDsByReturnType(m_work.testCase, m_work.className, t_rec.begin, t_rec.end);
			for (int i = 0; testIDs.size() > i; i++) {
				Integer k = Integer.valueOf(testIDs.get(i));
				if (m_work.testID > k) {
					if (!reusables.contains(testIDs.get(i) + "$_") && !isSnapshot(testIDs.get(i) + "$_")) { //$NON-NLS-1$
						reusables.add(testIDs.get(i) + "$_"); //$NON-NLS-1$
					}
				}
			}

			//ObjectRecordのうち再利用できるもの
			ArrayList<ObjectRecord> t_stacks1 = Tool._db().getReusableObjectRecord(m_work.testCase, m_work.className, m_work.testID, t_rec.begin);
			for (int j = 0; t_stacks1.size() > j; j++) {
				String num = t_stacks1.get(j).id.replaceFirst("\\$.+", ""); //$NON-NLS-1$ //$NON-NLS-2$
				Integer k = Integer.valueOf(num);
				if (m_work.testID > k) {
					if (!reusables.contains(t_stacks1.get(j).id) && !isSnapshot(t_stacks1.get(j).id)) {
						//重複を避けて登録する
						reusables.add(t_stacks1.get(j).id);//ObjectRecordのID
					}
					if (t_stacks1.get(j).id.matches("^[0-9]+\\$.+$")) { //$NON-NLS-1$
						//参照しているものがあれば重複を避けて登録する
						if (!refered.contains(t_stacks1.get(j).id) && isSnapshot(t_stacks1.get(j).id)) {
							refered.add(t_stacks1.get(j).id);
						}
					}
				}
			}
		}

		//ここからstackBoxに登録
		stackBox.addItem(m_work.stack);
		if (!m_work.stack.equals(m_stack0)) {
			//m_work.stackが既存インスタンスを指定している場合、指定解除するために、引数位置を選択できるようにする。
			stackBox.addItem(m_stack0);
		}

		for (int j = 0; j < reusables.size(); j++) {
			String t_obj = reusables.get(j);
			if (!refered.contains(t_obj)) {
				//参照されていないので最新

				stackBox.addItem(t_obj);
			}
		}
		stackBox.setSelectedIndex(0);

		if (!TestCaseEditor.unableMode) {
			if (is_pojo) {
				btnCreateFake.setEnabled(false);
				stackBox.setEnabled(true);
			} else {
				stackBox.setEnabled(false);
				btnCreateFake.setEnabled(true);
			}
		}
	}

	//引数のobjectIDがスナップショットのものか判定する。
	private boolean isSnapshot(String sid) {
		if (sid != null && sid.matches("^[0-9]+\\$[_0-9]+$")) {
			Integer t_id = Integer.valueOf(sid.replaceFirst("^([0-9]+)\\$[_0-9]+$", "$1"));
			TestCmdNode t_cmd = s_owner.m_snapshot;
			if (t_cmd != null) {
				if (t_cmd.getID() == t_id) {
					return true;
				}
			} else {
				//DBから取る。
				ArrayList<TestCaseRecord> t_list = Tool._db().getTestCaseList(s_owner.m_include, 0, 0, "", Tool.version);
				if (t_list.size() > 0) {
					String num = Integer.toString(t_list.get(0).snapshot);//TestCaseの名前がユニークと仮定。snapshotのID
					if (t_id.toString().equals(num)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	//stackのメソッド用引数もしくはコンストラクタ用のチェックは対象外の状態で呼ばれる。
	//あくまでもJSONのチェックのみ。
	private boolean checkJSONField(Class<?> xclass, String s_json) {
		if (isMap(xclass)) {
			//Map系は、ほぼそのままOK
			if (s_json != null && s_json.length() > 0) {
				return true;
			}
		}

		if (xclass.getName().startsWith("java.lang")) { //$NON-NLS-1$
			//ほぼprimitive。String,Integerなど。
			try {
				Object t_obj = Tool.getObjectfromJSON(xclass, s_json);
				if (t_obj == null) {
					return false;
				}
				return true;
			} catch (Exception e) {
				return false;
			}
		}

		@SuppressWarnings("unchecked")
		HashMap<String, String> t_map = (HashMap<String, String>) Tool.getObjectfromJSON(HashMap.class, s_json);

		for(Entry<String, String> entry : t_map.entrySet()) {
			String fname = entry.getKey();
			fname = fname.replaceFirst("\\(.*\\)", "");//cast情報があれば削除。フィールド名を抜き出す。 //$NON-NLS-1$ //$NON-NLS-2$

			Field t_f = Tool.getField(xclass, fname);
			if (t_f == null) {
				return false;//存在しないField
			}
		}
		return true;//jsonの中のフィールドは確かに存在する。
	}

	private boolean isMap(Class<?> xc) {
		Class<?>[] clist = xc.getInterfaces();
		for (int i = 0; i < clist.length; i++) {
			if (clist[i].getName().equals("java.util.Map") || isMap(clist[i])) { //$NON-NLS-1$
				return true;
			}
		}
		return false;
	}


	//拡張JSONのためにJSONChooserを呼びCaret位置に挿入する。
	private boolean insertByJSONChooser() {
		String s_str = textJSON.getText();
		Caret t_ca = textJSON.getCaret();
		s_str = s_str.substring(0,t_ca.getDot());
		if (s_str != null) {
			String cname = null;

			//引数のクラス指定の場合
			final Pattern t_pat1 = Pattern.compile("[{,\\s\"]\\$[0-9]+\\(([\\w\\.\\[\\]]+)\\)[\\s\"]*:$"); //$NON-NLS-1$
			Matcher t_m = t_pat1.matcher(s_str);
			if (t_m.find()) {
				cname = t_m.group(1);
			} else {
				//キャストでクラス指定の場合
				final Pattern t_pat2 = Pattern.compile("[{,\\s\"][\\$\\w]+[\\s\"]*:\\s*\\([\\w\\.\\[\\]]\\)$"); //$NON-NLS-1$
				t_m = t_pat2.matcher(s_str);
				if (t_m.find()) {
					cname = t_m.group(1);
				}
			}
			if (cname != null) {
				ArrayList<JSONRecord> t_data = Tool._db().getJSONRecWhere(cname, null, Tool.version);
				if (t_data.size() > 0) {
					JSONChooser chooser = new JSONChooser(this, t_data);
					chooser.setVisible(true);
					if (chooser.is_ok) {
						int pos = textJSON.getCaretPosition();
						String str_h = textJSON.getText();
						String str_tail = str_h.substring(pos);
						String t_str = chooser.m_json;

						str_h = str_h.substring(0, pos);
						str_h += t_str + str_tail;
						textJSON.setText(str_h);
						textJSON.setCaretPosition(pos + t_str.length());
						m_work.setJSON(textJSON.getText());
					}
				} else {
					Tool.alertMSG(null, Messages.getString("ArgumentEditor.64")); //$NON-NLS-1$
				}
				return true;
			}
		}
		return false;
	}

	//JSON のsave処理。通常JSONの時だけに呼ばれる。
	private void saveJson(String name, boolean newFlag) {
		JSONRecord t_j = null;
		if (newFlag) {
			//insert
			t_j = new JSONRecord(2);
			t_j.name = name;
			t_j.className = m_work.className;
			t_j.content = m_work.jSON;
		} else {
			t_j = new JSONRecord(1);
			t_j.name = name;
			t_j.className = m_work.className;
			t_j.content = m_work.jSON;
		}

		//fieldsを埋める。
		HashMap<String, String> f_map = new HashMap<String, String>();
		try {
			f_map = Fson.getFieldMapOfJson(m_work.jSON);
		} catch (ParseException e1) {
			Tool.logIfDebug(e1, " Illegal Json.");
			return;
		}
		boolean _1st = true;
		String t_res = ""; //$NON-NLS-1$
		for(Entry<String, String> entry : f_map.entrySet()) {
			//今回、新規追加
			if (!_1st) {
				t_res += ",\n"; //$NON-NLS-1$
			} else {
				_1st = false;
			}
			t_res += entry.getKey();
		}
		t_j.fields = t_res;

		if (t_j != null) {
			try {
				//ここでDB更新
				Tool._db().updateRecordBySQL(t_j.getUpdateSQL(), true);
			} catch (SQLException e) {
				Tool.alertMSG(null, Messages.getString("ArgumentEditor.18") + e.getMessage()); //$NON-NLS-1$
			}
		}
	}
}
