/** * @version $Id: AcquireReferenceRelation.java 1839 2014-04-16 02:33:51Z yukihiro-kinjyo $ * * 2012/07/26 15:25:28 * @author wataru-higa * * Copyright 2011-2014 TIDAコンソーシアム All Rights Reserved. */ package com.tida_okinawa.corona.ui.views.pattern.reference; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreeNode; import com.tida_okinawa.corona.correction.parsing.model.Link; import com.tida_okinawa.corona.correction.parsing.model.Pattern; import com.tida_okinawa.corona.correction.parsing.model.PatternContainer; import com.tida_okinawa.corona.correction.parsing.model.PatternRecord; import com.tida_okinawa.corona.io.IoActivator; import com.tida_okinawa.corona.io.model.dic.ICoronaDic; /** * 部品と部品を参照する構文パターンの親子関係(ツリー)を作成するクラス * * @author wataru-higa * */ public class AcquireReferenceRelation { /** * 部品と部品を参照している構文パターンの関係ツリーを作成するメソッド * 部品と部品を参照している構文パターンの親子関係データを返却する * * @param patternRecordList * 辞書内すべての構文パターン * @param selectedPattern * エディタで選択された要素または構文パターン * @return 部品と部品を参照している構文パターンの親子関係データを返却(TreeNode) */ public TreeNode[] createRelation(List<PatternRecord> patternRecordList, IStructuredSelection selectedPattern) { Object[] selectParts = selectedPattern.toArray(); List<PatternRecord> selectedPatternRecordList = getTop(selectParts); List<List<PatternRecord>> accordanceToParent = getAccordanceChildrenList(patternRecordList, selectedPatternRecordList); TreeNode[] treeNodeResult = setReferenceReleationTree(selectedPatternRecordList, accordanceToParent); return treeNodeResult; } /** * パターンエディタで選択された要素から最上位の要素(構文パターン)を取得するメソッド * 同じ構文パターンがリストへ格納されないように重複判定処理も行う * * @param selectPattern * パターンエディタで選択された要素 * @return エディタで選択された構文パターンのリストを返却 */ private static List<PatternRecord> getTop(Object[] selectPattern) { List<PatternRecord> patternRecordParentList = new ArrayList<PatternRecord>(); for (Object parts : selectPattern) { Pattern pattern = (Pattern) parts; // 選択された要素に親要素があれば親要素を取得 while (pattern.getParent() != null) { pattern = pattern.getParent(); } // 重複チェックの為、同じ構文パターンでなければリストへ追加 if (!patternRecordParentList.contains(pattern)) { patternRecordParentList.add((PatternRecord) pattern); } } return patternRecordParentList; } /** * 部品を基に部品を参照している構文パターンを抽出するメソッド * 抽出された構文パターンは部品の子としてリストへ格納する * selectedPatternRecordListのi番目と戻り値のi番目が対応するように子のリストを格納している * * @param allPatternRecordList * 辞書内すべての構文パターン * @param selectedPatternRecordList * 部品リスト * @return 部品に対する子のリスト * */ private List<List<PatternRecord>> getAccordanceChildrenList(List<PatternRecord> allPatternRecordList, List<PatternRecord> selectedPatternRecordList) { List<List<PatternRecord>> ret = new ArrayList<List<PatternRecord>>(); // 部品リストの分、処理を繰り返す for (PatternRecord selectedPattern : selectedPatternRecordList) { List<PatternRecord> childrenList = new ArrayList<PatternRecord>(); // 辞書内すべての構文パターンの分、処理を繰り返す for (PatternRecord patternRecord : allPatternRecordList) { // 選択した部品と同等でない場合にLINK検索処理を実行する if (!selectedPattern.equals(patternRecord)) { // 選択した構文パターン(部品)が参照元で使用されていれば子リストへ追加 if (searchLink(selectedPattern, patternRecord)) { childrenList.add(patternRecord); } } } ret.add(childrenList); } return ret; } /** * 部品が検索対象の構文パターン内で使用されているかをチェックするメソッド * 検索対象構文パターン内のLINK要素IDと部品IDが一致した場合にtrueを返却 * * @param targetPattern * 部品 * @param pattern * 検索対象構文パターン * @return LINK要素IDと部品IDが一致した場合にtrueを返却 */ private boolean searchLink(PatternRecord targetPattern, PatternContainer pattern) { for (Pattern child : pattern.getChildren()) { // 選択した部品IDとLINK要素IDが一致すればフラグをセット if (child instanceof PatternContainer) { if (child.hasChildren()) { if (searchLink(targetPattern, (PatternContainer) child)) { return true; } } } else if (child instanceof Link) { if (targetPattern.getIPattern().getId() == ((Link) child).getId()) { return true; } } } return false; } /** * TreeNodeに部品と部品を参照している構文パターンの親子関係を紐付けするメソッド * * @param selectedPatternRecordList * 部品リスト * @param children * 部品を参照している構文パターンのリスト * @return 部品と部品を参照している構文パターンの親子関係を返却(TreeNode) */ private static TreeNode[] setReferenceReleationTree(List<PatternRecord> selectedPatternRecordList, List<List<PatternRecord>> children) { TreeNode[] treeNode = new TreeNode[selectedPatternRecordList.size()]; int parentIndex = 0; // 部品を親に設定 for (PatternRecord parent : selectedPatternRecordList) { treeNode[parentIndex] = new TreeNode(new ReferenceRelationViewModel(parent.toString(), parent.getIPattern().isParts())); // 部品を参照している構文パターンを子へ設定 List<PatternRecord> childrenPattern = children.get(parentIndex); if (childrenPattern.size() == 0) { // 部品を参照している構文パターンがない場合 TreeNode[] child = new TreeNode[1]; child[0] = new TreeNode(new ReferenceRelationViewModel("参照されている構文パターンはありません", null)); child[0].setParent(treeNode[parentIndex]); treeNode[parentIndex].setChildren(child); } else { // 部品を参照している構文パターンがある場合 TreeNode[] childNode = new TreeNode[childrenPattern.size()]; int childIndex = 0; for (PatternRecord child : childrenPattern) { int dicId = child.getIPattern().getComprehensionDicId(); ICoronaDic coronaDic = IoActivator.getService().getDictionary(dicId); // 辞書名がnullでない場合に辞書名を表示 if (coronaDic != null) { childNode[childIndex] = new TreeNode(new ReferenceRelationViewModel(child.toString() + " (" + coronaDic.getName() + ")", child .getIPattern().isParts())); } else { childNode[childIndex] = new TreeNode(new ReferenceRelationViewModel(child.toString(), child.getIPattern().isParts())); } childNode[childIndex].setParent(treeNode[parentIndex]); childIndex++; } treeNode[parentIndex].setChildren(childNode); } parentIndex++; } return treeNode; } }