Eclipseの検索 >> 検索 にタブ状に表示される、検索インタフェースの拡張ポイントを使ってみました。ちなみにEclipseの検索機能って、これ↓のことです。
検索画面
結果画面
この拡張ポイントはいろんな機能やロジックが組み合わさっているのでまずそれをまとめてみます。
このように様々なモノがあるため、結構大変です。いっこづつ見ていきましょう。
まずどんな検索機能を作るかですが、workspace内の○○を検索する、とかでもいいんですが、いままでGooglePlugin?を作ってきたので、この検索ロジックを使用することにしました。検索ダイアログで、検索ボタンをクリックするとGoogle検索が行われて結果が、検索ビューに表示されるようにしてみます。
ちなみに必須プラグインは
org.eclipse.search
みたいですね。でもこれ入れると、ツールバーとかに勝手にボタンが付いちゃう。うざいけど、取り方がわからんです。
さあ、やってみましょう。
検索ロジックは以下の通り。GoogleのWEB Services APIを用いています。
GoogleSearchResult googleResult = GoogleCorePlugin.getDefault() .search("xxxxxxxxxxxxxxxx", [入力文字列]); ResultElement[] resultElements = googleResult.getResultElements(); for (int i = 0; i < resultElements.length; i++) { // 各ResultElementが検索結果一件に対応しています }
本質の箇所でないんで、まあこんな感じです。
続いて検索クエリクラスです。このクラスは先の検索ロジックを呼びだし、Eclipseが提供する検索結果クラスを生成します。検索クエリクラスのインタフェースは org.eclipse.search.ui.ISearchQuery? です。このインタフェースで、重要なのは以下の二つのメソッドです。
IStatus run(IProgressMonitor monitor); ISearchResult getSearchResult();
IStatus run(IProgressMonitor? monitor); で先の検索ロジックを呼び出して検索処理を実行します。 そして ISearchResult? getSearchResult?(); で検索結果を返します。ISearchResult?が「検索結果クラス」です。
このクエリのインタフェースですが、おもしろいのはrun実行中にもgetSearchResult?が呼ばれるということです。たとえばrunメソッド内でworkspaceを検索中に「いまどうなってるの??」とEclipseが問い合わせてきて、そのときにgetSearchResult?が呼び出されるわけですね。つまり検索中にも結果をビューに表示してくれるわけです。確かにEclipseの検索I/Fって検索中にもマッチしたものが表示されるようになってますね。
今回の例では、ISearchQuery?を実装するTextSearchQuery?を作成しました。実装した内容は
IStatus run(IProgressMonitor monitor);
では検索処理を実行し、検索結果オブジェクトを生成しています。で、
ISearchResult getSearchResult();
では
public ISearchResult getSearchResult() { if (result == null) { result = new TextSearchResult(this); } return result; }
としてISearchResult?を作成して返しています。このメソッドは検索をしている途中にも随時呼ばれるのが注意点です。result変数はフィールドの変数で、型はISearchResult?を実装したTextSearchResult?です。詳細は後述として、次はこのISearchResult?を見てみます。
ではその検索結果クラスですが、このISearchResult?インタフェースは検索結果を保持しているクラスです。検索結果n件を保持するインタフェースとでもいえましょうか。このインタフェースにはテンプレートとなる抽象クラス org.eclipse.search.ui.text.AbstractTextSearchResult? があり、これを拡張して使うことが多いようです。で、このクラスを使った検索結果の内容の構築方法ですが、このクラスへ検索結果n件たちを
public void addMatch(Match match);
などのメソッドを使って追加していきます。このorg.eclipse.search.ui.text.Matchというクラスが、検索結果一件に対応するクラスなんですね。このMatchクラスは
/** * Constructs a new Match object. * @param element the element that contains the match * @param unit the unit offset and length are based on * @param offset the offset the match starts at * @param length the length of the match */ public Match(Object element, int unit, int offset, int length)
となってますが、ようわからんですね。とりあえず引数のelementに、検索ビューに表示したいオブジェクトを渡しておけばよいみたいです。つまり今回のGoogle検索の例だと、org.eclipse.search.ui.ISearchQuery?の実装クラスTextSearchQuery?を作成し、このクラスの
public IStatus run(IProgressMonitor monitor);
メソッド内で、
ResultElement[] resultElements = googleResult.getResultElements(); for (int i = 0; i < resultElements.length; i++) { result.addMatch(new Match(resultElements[i], Match.UNIT_LINE, 0, 0)); }
としています。resultはさっきちょこっと出てきたTextSearchResult?クラス(AbstractTextSearchResult?を拡張している)です。内容は以下のようになっています*1。
public class TextSearchResult extends AbstractTextSearchResult { private final ISearchQuery query; public TextSearchResult(ISearchQuery query) { this.query = query; } public ISearchQuery getQuery() { return query; } ...省略 }
ここまでをまとめると
public void addMatch(Match match);を使ってISearchQuery?#run内で検索結果をaddMatchしていけばよい。
という感じになります。
さてここまでで検索結果を供給するビジネスロジックは完了しました。次はこれを操作したり結果を表示したりするビューなどの定義・作成です。これらは
検索ページ拡張ポイント(org.eclipse.search.searchPages) 検索結果ページ拡張ポイント(org.eclipse.search.searchResultViewPages)
を定義して対応するクラスを実装することで実現します。
次に画面の作成を行いますが、長くなってしまったので、別のページでまとめたいと思います。
この記事は
現在のアクセス:12828