Top / Eclipse / プラグイン開発のTIPS集 / Eclipseの検索画面を作成する

Eclipseの検索 >> 検索 にタブ状に表示される、検索インタフェースの拡張ポイントを使ってみました。ちなみにEclipseの検索機能って、これ↓のことです。

search.png

検索画面


result.png

結果画面

この拡張ポイントはいろんな機能やロジックが組み合わさっているのでまずそれをまとめてみます。

検索ページ拡張ポイント(org.eclipse.search.searchPages)
検索インタフェースを提供する拡張ポイントです。この拡張ポイントを定義すると、検索ダイアログにタブが表示されます。で拡張ポイントに記載したクラスで、タブ内の画面を構築していきます。
検索結果ページ拡張ポイント(org.eclipse.search.searchResultViewPages?)
検索した結果は、Eclipse謹製のの検索ビューに表示されますが、その中のウィジェットは自分で構築することができます。その画面を定義する拡張ポイントです。
検索ロジック
Eclipseフレームワークとは関係がない、いわゆる検索ロジックです。
検索クエリクラス(org.eclipse.search.ui.ISearchQuery?)
検索ロジックを呼び出すクエリクラスです。このクラスが先の検索ロジックを呼びだし、Eclipseが提供する検索結果クラスを生成します。
検索結果クラス(org.eclipse.search.ui.ISearchResult?)
Eclipseが提供する、検索結果の集合を表すクラスです。

このように様々なモノがあるため、結構大変です。いっこづつ見ていきましょう。

まずどんな検索機能を作るかですが、workspace内の○○を検索する、とかでもいいんですが、いままでGooglePlugin?を作ってきたので、この検索ロジックを使用することにしました。検索ダイアログで、検索ボタンをクリックするとGoogle検索が行われて結果が、検索ビューに表示されるようにしてみます。

class.png

ちなみに必須プラグインは

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が検索結果一件に対応しています
}

本質の箇所でないんで、まあこんな感じです。

検索クエリクラス org.eclipse.search.ui.ISearchQuery?

続いて検索クエリクラスです。このクラスは先の検索ロジックを呼びだし、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?を見てみます。

検索結果クラス org.eclipse.search.ui.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;
  }
  ...省略
}

ここまでをまとめると

  • org.eclipse.search.ui.ISearchQuery?の実装クラスが、検索の実行や検索結果オブジェクトの生成・保持まで担当する
  • 検索結果オブジェクトの型はorg.eclipse.search.ui.ISearchResult? である
  • org.eclipse.search.ui.ISearchResult?はテンプレートのorg.eclipse.search.ui.text.AbstractTextSearchResult?を拡張して使うことが多い。
  • org.eclipse.search.ui.text.AbstractTextSearchResult?を拡張したクラスで
    public void addMatch(Match match);
    を使ってISearchQuery?#run内で検索結果をaddMatchしていけばよい。

という感じになります。


さてここまでで検索結果を供給するビジネスロジックは完了しました。次はこれを操作したり結果を表示したりするビューなどの定義・作成です。これらは

検索ページ拡張ポイント(org.eclipse.search.searchPages)
検索結果ページ拡張ポイント(org.eclipse.search.searchResultViewPages)

を定義して対応するクラスを実装することで実現します。

画面の作成

次に画面の作成を行いますが、長くなってしまったので、別のページでまとめたいと思います。

関連リンク


この記事は

選択肢 投票
おもしろかった 2  
そうでもない 2  

Top / Eclipse / プラグイン開発のTIPS集 / Eclipseの検索画面を作成する

現在のアクセス:10919


*1 クエリと検索結果は相互参照してますね。。

添付ファイル: fileclass.png 579件 [詳細] fileresult.png 464件 [詳細] filesearch.png 489件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-01-12 (金) 14:29:29 (619d)