/*
 * Copyright (c) 2007, Going Dot Com Inc. All rights reserved.
 */

package jp.co.going.xbrl.sample;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import jp.co.going.xbrl.common.XbException;
import jp.co.going.xbrl.sample.dao.XbEtcDao;
import jp.co.going.xbrl.sample.dao.XbItemDao;
import jp.co.going.xbrl.sample.dao.XbItemFootnoteDao;
import jp.co.going.xbrl.sample.dao.XbItemTopDao;
import jp.co.going.xbrl.sample.dao.XbMappingDao;
import jp.co.going.xbrl.sample.dao.obj.XbEtcObj;
import jp.co.going.xbrl.sample.dao.obj.XbItemObj;
import jp.co.going.xbrl.sample.dao.obj.XbItemTopObj;
import jp.co.going.xbrl.sample.dao.obj.XbMainEtcObj;
import jp.co.going.xbrl.sample.dao.obj.XbMappingObj;

/**
 * @author Masako Okayasu
 */
@SuppressWarnings("serial")
public class XbMapping extends XbTreeDataSet implements HyperlinkListener, ActionListener {

	private Connection conn = null;
	private XbItemTopDao instanceDao = null;
	private XbItemDao itemDao = null;
	private XbMappingDao mappingDao = null;
	private XbEtcDao etcDao = null;
	private XbItemFootnoteDao itemFootnoteDao = null;

	private XbMyTreeNode rootNode = new XbMyTreeNode("（登録済リスト）");
	private JButton expButton = new JButton("展開");

	private JButton taxExpButton = new JButton("展開");
	private XbMyTreeNode taxRootNode = null;
	private JTree taxTree = null;
	private DefaultTreeModel taxTreeModel = null;
	private XbMyTreeNode taxSelectNode = null;
	private String taxSelectNodeName = null;

	private JTable taxTable = null;
	private DefaultTableModel taxTableModel = null;
	private String[] dataList = null;
	private int TAX_ID=0, FOLDER=1, TAX_NAME=2, USER_ITEM_ID=3, USER_ITEM_NAME=4;
	private int PRECISION=5, DECIMAL=6, ITEM_FOOT=7, DESCRIPT=8, TUPLE=9;

	private JPopupMenu taxPopMenu = null;
	private JMenuItem[] taxPopMenuItem = new JMenuItem[2];

	private JTextField urlTextField = null;
	private JButton fileButton = null;
	private JButton moveButton = null;
	private JEditorPane htmlPane = null;

	private int taxMenuFlag = 0;
	private int taxSelectRow = 0;
	private String itemLang = null;
	private long instanceID = 0;
	private HashMap<Long, TreePath> parent_id = null;

	private String prefix = "";
	private String uri = "";

	/**
	 * コンストラクタ
	 */
	public XbMapping(Connection conn) {
		this.conn = conn;

		try {
			instanceDao = XbItemTopDao.getInstance(conn);
			itemDao = XbItemDao.getInstance(conn);
			mappingDao = XbMappingDao.getInstance(conn);
			etcDao = XbEtcDao.getInstance(conn);
			itemFootnoteDao = XbItemFootnoteDao.getInstance(conn);			


			// インスタンス文書の種類選択
			ArrayList<XbItemTopObj> list = instanceDao.selectAll();
			String optionDefault = "";
			String[] optionList = new String[list.size()];
			XbItemTopObj obj = null;

			for(int i=0; i<list.size(); i++) {
				obj = list.get(i);
				optionList[i] = obj.getItem_name();
				optionDefault = optionList[0];
			}

			Object instance = JOptionPane.showInputDialog(
					this,
					"マッピング処理を実行する\nインスタンス文書の種類を選択して下さい。",
					"入力",
					JOptionPane.INFORMATION_MESSAGE,
					null,
					optionList,
					optionDefault);

			if(instance != null && !instance.equals("")) {

				// 選択されたインスタンス文書より、
				// タクソノミーグループID (instanceID)、タクソノミー項目IDを取得
				long taxItemID = 0;
				for(int i=0; i<list.size(); i++) {
					obj = list.get(i);
					if(obj.getItem_name().equals(instance.toString())) {
						instanceID = obj.getTaxonomy_group_id();
						taxItemID = obj.getTaxonomy_item_id();
						itemLang = obj.getItem_lang();
						break;
				}	}

				setTitle("XBRL Toolkit <-> User's Table : Mapping");
				setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

				try {
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
				} catch (Exception e) {
					e.printStackTrace();
				}

				Container container = getContentPane();
				container.setLayout(new BorderLayout());

				JPanel TaxPanel = TaxPanel(instance.toString(), taxItemID);
				JPanel BrowserPanel = BrowserPanel();
				JPanel MappingPanel = MappingPanel();
				JPanel SubmitPanel = SubmitPanel();

				submitButton.addActionListener(this);
				submitButton.setEnabled(false);
				closeButton.addActionListener(this);

				JPanel mapping = new JPanel();
				mapping.setLayout(new FlowLayout());
				mapping.add(TaxPanel);
				mapping.add(BrowserPanel);

				container.add(mapping, BorderLayout.NORTH);
				container.add(MappingPanel, BorderLayout.CENTER);
				container.add(SubmitPanel, BorderLayout.SOUTH);

				// Footnoteの初期値
				ArrayList<XbEtcObj> list3 = etcDao.selectAll(etcType.get(FOOTNOTE));
				dataList = new String[list3.size()];
				for(int i=0; i<list3.size(); i++) {
					XbEtcObj obj3 = list3.get(i);
					dataList[i] = String.valueOf(obj3.getEtc_id()) + ". " + obj3.getEtc_name();
				}

				popTaxMenu();
				setTaxMouseAdapter();
				setFootnoteAdapter();

			} else {
				getContentPane().add(setPanel(new JLabel("　入力エラー")));
			}

			pack();

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 画面Header欄の生成
	 */
	private JPanel HeaderPanel() {
		JPanel HeaderPanel = new JPanel();
		HeaderPanel.setLayout(new BorderLayout());

		HeaderPanel.add(new JLabel("　【 タクソノミー項目一覧 】"), BorderLayout.WEST);

		taxExpButton.addActionListener(this);
		HeaderPanel.add(setPanel(taxExpButton), BorderLayout.EAST);

		return HeaderPanel;
	}

	/**
	 * タクソノミー項目ツリーの生成
	 */
	private JPanel TaxPanel(
			String instanceName,
			long taxonomy_item_id
		) {

		JPanel TaxPanel = new JPanel();
		TaxPanel.setLayout(new BorderLayout());

		TaxPanel.add(HeaderPanel(), BorderLayout.NORTH);

		try {
			taxRootNode = new XbMyTreeNode("（" + instanceName + "）");
			taxRootNode.setType("root");

			parent_id = new HashMap<Long, TreePath>();
			parent_id.put((long)taxonomy_item_id, new TreePath(taxRootNode.getPath()));

			// 枝ノードの生成
			Iterator ite = parent_id.entrySet().iterator();
			while(ite.hasNext()) {
				parent_id = new HashMap<Long, TreePath>();

				while(ite.hasNext()) {
					Entry ent = (Entry)ite.next();
					long key = (Long)ent.getKey();
					TreePath val = (TreePath)ent.getValue();
					XbMyTreeNode parentNode = (XbMyTreeNode)val.getLastPathComponent();

					ArrayList<XbItemObj> list = itemDao.selectAll(instanceID, key, itemLang);
					for(int j=0; j<list.size(); j++) {
						XbItemObj obj = list.get(j);

						String nodeTitle = obj.getItem_name() + (obj.getItem_type().equals("item") ? "" : "  --- ★タプル★");
						XbMyTreeNode nameNode = new XbMyTreeNode(nodeTitle);
						nameNode.setType(obj.getItem_type());
						nameNode.setID(obj.getTaxonomy_item_id());
						parentNode.add(nameNode);

						parent_id.put(obj.getTaxonomy_item_id(), new TreePath(nameNode.getPath()));
				}	}

				ite = parent_id.entrySet().iterator();
			}

			taxTreeModel = new DefaultTreeModel(taxRootNode);
			taxTree = new JTree(taxTreeModel);
			taxTree.setScrollsOnExpand(true);
			taxTree.setToggleClickCount(1);
			taxTree.setSelectionRow(0);
			taxSelectNode = taxRootNode;

			JScrollPane scroll = new JScrollPane();
			scroll.getViewport().setView(taxTree);
			scroll.setPreferredSize(new Dimension(400, 300));
			TaxPanel.add(scroll, BorderLayout.CENTER);

			TaxPanel.add(FootnotePanel(conn), BorderLayout.SOUTH);

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return TaxPanel;
	}

	/**
	 * Footnoteツリーの生成
	 */
	private JPanel FootnotePanel(Connection conn) {
		JPanel FootnotePanel = new JPanel();
		FootnotePanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
		FootnotePanel.setLayout(new BorderLayout());

		JLabel title = new JLabel("　【 " + nameList.get(FOOTNOTE) + " <" + FOOTNOTE + "> 】");
		FootnotePanel.add(title, BorderLayout.WEST);

		expButton.addActionListener(this);
		FootnotePanel.add(setPanel(expButton), BorderLayout.EAST);

		FootnotePanel.add(TreePanel(FOOTNOTE, rootNode, instanceID, false, conn), BorderLayout.SOUTH);

		return FootnotePanel;
	}

	/**
	 * ユーザ環境指定欄の生成
	 */
	private JPanel BrowserPanel() {
		JPanel BrowserPanel = new JPanel();
		BrowserPanel.setLayout(new BorderLayout());

		JLabel title = new JLabel("　【 お客様側環境 】");
		title.setPreferredSize(new Dimension(200, 21));

		urlTextField = new JTextField();
		urlTextField.setFocusAccelerator('d');
		urlTextField.addActionListener(this);

		fileButton = new JButton("参照");
		fileButton.addActionListener(this);

		moveButton = new JButton("開く");
		moveButton.addActionListener(this);

		htmlPane = new JEditorPane();
		htmlPane.setEditable(false);
		htmlPane.addHyperlinkListener(this);
		htmlPane.setContentType("text/html");

		JPanel buttonPanel = new JPanel(new BorderLayout());
		buttonPanel.add(fileButton, BorderLayout.WEST);
		buttonPanel.add(moveButton, BorderLayout.EAST);

		JPanel northPanel = new JPanel(new BorderLayout());
		northPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
		northPanel.add(new JLabel("科目一覧 ﾌｧｲﾙﾊﾟｽ："), BorderLayout.WEST);
		northPanel.add(urlTextField, BorderLayout.CENTER);
		northPanel.add(buttonPanel, BorderLayout.EAST);

		JScrollPane scroll = new JScrollPane(htmlPane);
		scroll.setPreferredSize(new Dimension(500, 525));
		scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

		BrowserPanel.add(title, BorderLayout.NORTH);
		BrowserPanel.add(northPanel, BorderLayout.CENTER);
		BrowserPanel.add(scroll, BorderLayout.SOUTH);

		return BrowserPanel;
	}

	/**
	 * タクソノミー - ユーザ環境のマッピング（手入力）
	 */
	private JPanel MappingPanel() {
		JPanel MappingPanel = new JPanel();
		MappingPanel.setLayout(new BorderLayout());

		try {
			String[] tableHeader = new String[]{
					"ﾀｸｿﾉﾐｰｱｲﾃﾑID",
					"フォルダ",
					"タクソノミーアイテム名称",
					"ﾕｰｻﾞｱｲﾃﾑID",
					"ユーザアイテム名称",
					"Precision",
					"Decimal",
					"フットノート",
					"備考",
					"ﾀﾌﾟﾙの子"};

			ArrayList<XbMappingObj> temp = mappingDao.selectAll(instanceID, itemLang);
			String[][] tableData = new String[temp.size()][4];

			for(int i=0; i<temp.size(); i++) {
				XbMappingObj obj1 = temp.get(i);

				XbItemObj obj2 = itemDao.select(instanceID, obj1.getTaxonomy_item_id(), itemLang);
				if(obj2==null) {
					continue;
				}

				String taxItemName = obj2.getItem_name();
				String folderName = "";
				do {
					obj2 = itemDao.select(instanceID, obj2.getParent_taxonomy_item_id(), itemLang);
					if(obj2 != null)  folderName = obj2.getItem_name() + " - " + folderName;
				}
				while(obj2 != null);

				tableData[i] = new String[]{
						"  " + obj1.getTaxonomy_item_id(),
						folderName,
						taxItemName,
						String.valueOf(obj1.getUser_item_id()),
						"項目１",
						String.valueOf(obj1.getItem_precision()),
						String.valueOf(obj1.getItem_decimal()),
						obj1.getEtc_id()==0 ? "" : obj1.getEtc_id() + ". " + obj1.getEtc_name(),
						obj1.getDescription(),
						String.valueOf(obj1.getTuple_child_flag())
				};
			}

			JLabel title = new JLabel("　【 タクソノミー  <->  お客様側環境 マッピング情報 】");
			title.setPreferredSize(new Dimension(800, 21));

			taxTableModel = new DefaultTableModel(tableData, tableHeader) {
				public boolean isCellEditable(int row, int column) {
					if(column <= TAX_NAME || column==ITEM_FOOT || column==TUPLE)
						return false;
					else
						return true;
			}	};

			taxTable = new JTable(taxTableModel);
			taxTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
			taxTable.setToolTipText(TOOLTIP2);

			TableColumn col = taxTable.getColumnModel().getColumn(TAX_ID);
			col.setMinWidth(95);
			col.setMaxWidth(95);

			col = taxTable.getColumnModel().getColumn(FOLDER);
			col.setMinWidth(130);

			col = taxTable.getColumnModel().getColumn(TAX_NAME);
			col.setMinWidth(130);

			col = taxTable.getColumnModel().getColumn(USER_ITEM_ID);
			col.setMinWidth(85);
			col.setMaxWidth(85);

			col = taxTable.getColumnModel().getColumn(USER_ITEM_NAME);
			col.setMinWidth(130);

			col = taxTable.getColumnModel().getColumn(TUPLE);
			col.setMinWidth(62);
			col.setMaxWidth(62);

			JScrollPane scroll = new JScrollPane(taxTable);
			scroll.setPreferredSize(new Dimension(900, 182));

			MappingPanel.add(title, BorderLayout.NORTH);
			MappingPanel.add(scroll, BorderLayout.SOUTH);

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return MappingPanel;
	}

	/**
	 * 右クリックメニューの生成
	 */
	private void popTaxMenu() {
		taxPopMenu = new JPopupMenu();

		if(taxMenuFlag==1) {
			taxPopMenuItem[0] = new JMenuItem("マッピング情報追加");
			taxPopMenuItem[0].addActionListener(this);
			taxPopMenu.add(taxPopMenuItem[0]);
		}

		if(taxMenuFlag==2) {
			taxPopMenuItem[1] = new JMenuItem("削除");
			taxPopMenuItem[1].addActionListener(this);
			taxPopMenu.add(taxPopMenuItem[1]);
	}	}

	/**
	 * MouseAdapterの登録
	 */
	private void setTaxMouseAdapter() {
		taxTree.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				taxSelectRow = taxTree.getRowForLocation(e.getX(), e.getY());
				if(taxSelectRow != -1) {
					taxTree.setSelectionRow(taxSelectRow);
					getTableSelectRow();

					if(taxSelectNode.getType().equals(TAX_ITEM)) {
						if(SwingUtilities.isRightMouseButton(e)) {
							taxMenuFlag = 1;
							popTaxMenu();
							taxPopMenu.show(e.getComponent(), e.getX(), e.getY());
		}	}	}	}	});

		taxTable.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				taxTable.setRowSelectionAllowed(true);

				int selectRow = taxTable.getSelectedRow();
				if(selectRow >= 0) {
					getTreeSelectRow();

					if(SwingUtilities.isRightMouseButton(e)) {
						taxMenuFlag = 2;
						popTaxMenu();
						taxPopMenu.show(e.getComponent(), e.getX(), e.getY());
		}	}	}	});

		taxTableModel.addTableModelListener(new TableModelListener() {
			public void tableChanged(TableModelEvent e) {
				submitButton.setEnabled(true);
		}	});
	}

	/**
	 * Footnote欄の処理の追加登録
	 */
	private void setFootnoteAdapter() {
		tree.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				if(e.getClickCount()==2) {
					addFootnote();
		}	}	});
	}
	// Footnote欄の処理の追加登録
	private void addFootnote() {
		int i = getTableSelectRow();
		if(i >= 0) {
			Object itemFoot = taxTable.getValueAt(i, ITEM_FOOT);
			if(itemFoot != null && !itemFoot.equals("")) {
				if(JOptionPane.showConfirmDialog(this, "更新してよろしいですか？") == JOptionPane.YES_OPTION) {
					taxTable.setValueAt(selectNode.getID() + ". " + selectNodeName , i, ITEM_FOOT);
			}	}
			else {
				taxTable.setValueAt(selectNode.getID() + ". " + selectNodeName, i, ITEM_FOOT);
	}	}	}

	/**
	 * ファイル選択ダイアログを開き、選択されたファイルを読み込む。
	 */
	private void load() {
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setDialogTitle("お客様側環境 ER図の選択");
		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		fileChooser.addChoosableFileFilter(new FileFilter() {
			public boolean accept(File file) {
				if(file.isDirectory()) return true;
				return file.getName().toLowerCase().endsWith(".html");
			}
			public String getDescription() {
				return "HTMLファイル(*.html)";
			}
		});
		String filePath = null;

		if(fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();
			filePath = file.getPath();

			if(filePath != null) {
				urlTextField.setText("file:///" + filePath.replace("\\", "/"));
	}	}	}

	/**
	 * JTextFieldに記述されたＵＲＬをJEditorPaneに表示する。
	 */
	private void setPage() {
		String url = urlTextField.getText().trim();
		if(url.length() > 0) {
			try {
				htmlPane.setPage(url);
			} catch (IOException e) {
				JOptionPane.showMessageDialog(this, "読み込みエラーが発生しました。", "読み込みエラー", JOptionPane.ERROR_MESSAGE);
	}	}	}

	/**
	 * HyperLink のイベントを取得
	 */
	public void hyperlinkUpdate(HyperlinkEvent e) {
		if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED && taxSelectNode.getID() > 0) {
			String[] temp = e.getDescription().split("&");
			addTableRow(temp[0], temp[1]);
	}	}

	/**
	 * タクソノミーアイテムの選択行の設定
	 */
	private void getTreeSelectRow() {
		int index = taxTable.getSelectedRow();
		long ID = Long.valueOf(taxTable.getValueAt(index, 0).toString().trim());

		taxTree.setSelectionRow(-1);
		getTreeSelectRow2(taxRootNode, ID);
	}
	// タクソノミーアイテム選択の追加処理
	private void getTreeSelectRow2(XbMyTreeNode Node, long ID) {
		for(int i=0; i<Node.getChildCount(); i++) {
			XbMyTreeNode childNode = (XbMyTreeNode)Node.getChildAt(i);

			if(childNode.getID() == ID) {
				taxTree.setSelectionPath(new TreePath(childNode.getPath()));
				break;
			}

			// さらに深部へ
			if(childNode.getChildCount() > 0) {
				getTreeSelectRow2(childNode, ID);
	}	}	}

	/**
	 * マッピングテーブルの選択行の設定
	 */
	private int getTableSelectRow() {
		int index = -1;
		taxSelectNode = (XbMyTreeNode)taxTree.getLastSelectedPathComponent();

		if(taxSelectNode != null) {
			taxSelectNodeName = taxSelectNode.getUserObject().toString();
			long ID = taxSelectNode.getID();

			for(int i=0; i<taxTable.getRowCount(); i++) {
				taxTable.setRowSelectionAllowed(false); 
				if(Long.valueOf(taxTable.getValueAt(i, TAX_ID).toString().trim()) == ID) {
					taxTable.setRowSelectionAllowed(true);
					taxTable.setRowSelectionInterval(i, i);
					index = i;
					break;
		}	}	}
		return index;
	}

	/**
	 * マッピング情報の設定
	 */
	private void addTableRow(String userItemID, String userItemName) {
		int i = getTableSelectRow();
		if(i >= 0) {
			Object userItem  = taxTable.getValueAt(i, USER_ITEM_ID);

			if(userItem != null) {
				if(JOptionPane.showConfirmDialog(this, "更新してよろしいですか？") == JOptionPane.YES_OPTION) {
					taxTable.setValueAt(userItemID  , i, USER_ITEM_ID);
					taxTable.setValueAt(userItemName, i, USER_ITEM_NAME);
			}	}
			else {
				taxTable.setValueAt(userItemID  , i, USER_ITEM_ID);
				taxTable.setValueAt(userItemName, i, USER_ITEM_NAME);
		}	}
		else {
			XbMyTreeNode parentNode = (XbMyTreeNode)taxSelectNode.getParent();
			String tuple_child = parentNode.getType();
			String parentName = "";
			while(!parentNode.getUserObject().toString().equals(taxRootNode.getUserObject().toString())) {
				parentName = parentNode.getUserObject().toString() + " - " + parentName;
				parentNode = (XbMyTreeNode)parentNode.getParent();
			}

			String[] data = new String[]{
					"  " + taxSelectNode.getID(),
					parentName,
					taxSelectNodeName,
					userItemID,
					userItemName,
					"0",
					"0",
					"",
					"",
					tuple_child.equals(TAX_TUPLE) ? "1" : "0"};

			taxTableModel.insertRow(0, data);
			taxTable.setRowSelectionAllowed(true);
			taxTable.setRowSelectionInterval(0, 0);
	}	}

	/**
	 * Button のイベントを取得
	 */
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();

		// フットノート部分のPopMenuAction
		treePopMenuAction(source, dataList);

		if(source == taxPopMenuItem[0]) {
			addTableRow(null, null);
		}
		else if(source == taxPopMenuItem[1]) {
			if(JOptionPane.showConfirmDialog(this, "削除してよろしいですか？") == JOptionPane.YES_OPTION) {
				taxTableModel.removeRow(taxTable.getSelectedRow());
		}	}
		else if(source == urlTextField || source == moveButton){
			setPage();
		}
		else if(source == fileButton){
			load();
			setPage();
		}
		else if(source == submitButton){
			try {
				boolean rc = false;
				for(int i=0; i<taxTable.getRowCount(); i++) {

					// 入力チェック
					Object userItemID = taxTable.getValueAt(i, USER_ITEM_ID);
					Object precision  = taxTable.getValueAt(i, PRECISION);
					Object decimal    = taxTable.getValueAt(i, DECIMAL);
					Object itemFoot   = taxTable.getValueAt(i, ITEM_FOOT);
					Object tuple      = taxTable.getValueAt(i, TUPLE);
					Object descript   = taxTable.getValueAt(i, DESCRIPT);

					if(userItemID == null) {
						JOptionPane.showMessageDialog(this, "マッピングデータが不十分です。\n\n　　【" + taxTable.getValueAt(i, TAX_NAME) + "】\n\n");
						rc = true;
						break;
					}
					else {
						// レコードの存在確認
						long itemID = Long.valueOf(taxTable.getValueAt(i, TAX_ID).toString().trim());
						XbMappingObj mapping = mappingDao.select(instanceID, itemID);

						if(mapping==null) {

							long footnoteID = 0;
							int footnoteType = 0;
							if(itemFoot != null && !itemFoot.equals("")) {
								footnoteID = Long.valueOf(itemFoot.toString().substring(0, itemFoot.toString().indexOf(". ")));
								footnoteType = etcType.get(FOOTNOTE);
							}

							mapping = new XbMappingObj();
							mapping.setTaxonomy_group_id(instanceID);
							mapping.setTaxonomy_item_id(itemID);
							mapping.setUser_item_id(userItemID != null ? Long.valueOf(userItemID.toString().trim()) : null);
							mapping.setItem_precision(precision != null ? Integer.valueOf(precision.toString().trim()) : null);
							mapping.setItem_decimal(decimal != null ? Integer.valueOf(decimal.toString().trim()) : null);
							if(footnoteType > 0)  mapping.setEtc_type(footnoteType);
							if(footnoteID > 0)    mapping.setEtc_id(footnoteID);
							mapping.setTuple_child_flag(Integer.valueOf(tuple.toString().trim()));
							mapping.setDescription(descript != null ? descript.toString().trim() : null);
							mapping.setCreation_date(new Date());
							mappingDao.insert(mapping);
				}	}	}

				if(rc==false) {
					// Taxonomy Item - Footnote 登録
					getNodeValue(rootNode);
					conn.commit();

					JOptionPane.showMessageDialog(this, "データを登録しました。");
					submitButton.setEnabled(false);
				}
			} catch (XbException err) {
				try {
					err.printStackTrace();
					conn.rollback();
				}
				catch (Exception ex) {
					ex.printStackTrace();
				}
			} catch (Exception ex) { 
				ex.printStackTrace();
		}	}
		else if(source == closeButton){
			this.setVisible(false);
		}

		if(source == taxExpButton) {
			for(int i=0; i<taxTree.getRowCount(); i++) {
				taxTree.expandRow(i);
		}	}

		if(source == expButton) {
			for(int i=0; i<tree.getRowCount(); i++) {
				tree.expandRow(i);
		}	}
	}

	/**
	 * Taxonomy Item - Footnote 情報を登録
	 */
	private void getNodeValue(XbMyTreeNode Node) {
		try {
			for(int i=0; i<Node.getChildCount(); i++) {
				XbMyTreeNode childNode = (XbMyTreeNode)Node.getChildAt(i);
				String childNodeName = childNode.getUserObject().toString();

				// Taxonomy Item - Footnote 登録
				if(childNodeName.indexOf("<" + FOOTNOTE + ">： ") != -1) {
					String temp = childNodeName.substring(childNodeName.indexOf("Prefix=")+7).replace("\"", "");
					prefix = temp.substring(0, temp.indexOf("　"));
					uri = temp.substring(temp.indexOf("　URI=")+5);
				}
				else if(childNode.getID() > 0) {

					// レコードの存在確認
					XbMainEtcObj mainEtcObj = itemFootnoteDao.select(instanceID, Node.getID(), childNode.getID()); 

					if(mainEtcObj==null) {
						mainEtcObj = new XbMainEtcObj();
						mainEtcObj.setMain_id(instanceID);
						mainEtcObj.setEtc_type(etcType.get(FOOTNOTE));
						mainEtcObj.setEtc_id(childNode.getID());
						mainEtcObj.setParent_etc_id(Node.getID());
						mainEtcObj.setPrefix(prefix);
						mainEtcObj.setUri(uri);
						mainEtcObj.setCreation_date(new Date());
						itemFootnoteDao.insert(mainEtcObj);
				}	}

				// さらに深部へ
				if(childNode.getChildCount() > 0) {
					getNodeValue(childNode);
				}
			}
		} catch (Exception ex) { 
			ex.printStackTrace();
		}
	}
}