目次


Apache Derby で Eclipse プラグインを開発する

リソース索引付け機能を使用したデモ

Comments

Apache Derby と Eclipse プラグイン

Eclipse は強力な IDE プラットフォームで、GUI コンポーネントの作成に使用するフレームワーク (SWT、JFaces など) や、データの操作に使用するフレームワーク (Eclipse Modeling Framework など) をサポートします。Eclipse の最も感動的な特徴の 1 つは、プラグインを新規に作成して IDE プラットフォームの機能を拡張できることです。Eclipse では上記のフレームワークに限らず、Apache Derby データベースをはじめとするさまざまな人気のフレームワークでプラグインを開発できます。

この記事では、リソース索引付け機能を使って、Derby データベースで Eclipse プラグインを開発する方法を紹介します。Derby データベースを Eclipse に組み込んで使用すれば、セキュリティーやネットワークの問題 (接続が不安定になったり、遅延が長くなるなど) が一切ない SQL データベースをクライアント側に作成できます。情報を保管し、前に保管されたデータを素早く検索する簡単な方法としては、SQL データベースと JDBC API を使用します。

この記事で取り上げる話題は、以下のとおりです。

  • Derby データベースと Eclipse プラットフォームの統合
  • Derby データベースを使用した Eclipse でのデータ操作
  • Eclipse Builder フレームワークを使用したリソースの索引付け

作業の開始

Derby データベースを Eclipse 内で使用できるようにするには、最初のステップとしてまず、Derby Eclipse プラグインをダウンロードします。Latest Official Release セクションにリストされたリンクを選択してください。このパッケージには、以下の 3 つのプラグインがあります。

  • Derby コア・プラグイン。Eclipse プラットフォームに Derby サポートを提供します。
  • Derby ユーザー・インターフェース (UI) プラグイン。Eclipse プラットフォーム内の Derby データベースを操作するための UI コンポーネントを提供します。
  • Derby UI ドキュメンテーション・プラグイン。UI プラグインに関するドキュメンテーションを提供します。

Derby コア・プラグインによって、Derby サーバーおよびクライアント・ライブラリーが使用できるようになります。その結果、Eclipse 内で Derby データベースを作成したり、あるいは既存のデーベースに接続できるようになります。Derby UI プラグインは、Derby データベースを使用するアプリケーションを開発する際に役立つコンポーネントとツールを提供します。例えば、このプラグインによって、既存のデータベースとの接続、データベースへの SQL クエリーの送信が可能になります (詳細情報へのリンクについては、「参考文献」セクションを参照)。

これらのプラグインをインストールするには、以下のステップに従ってください。

  1. ダウンロードしたパッケージから、Eclipse プラグインのディレクトリー (例えば、/eclipse/plugins) にファイルを解凍します。
  2. Eclipse を起動 (または再起動) し、Help > About Eclipse SDK > Plug-in details の順にクリックして、プラグインが正しくインストールされていることを確認します。図 1 に示すように、Derby プラグインがリスト内に表示されているはずです。
図 1. Eclipse プラググイン・リスト内の Derby プラグイン
図 1. Eclipse プラググイン・リスト内の Derby プラグイン
図 1. Eclipse プラググイン・リスト内の Derby プラグイン

: この記事に付属のサンプル・アプリケーションをテストするには、少なくとも Derby コア・プラグインが必要です。

Derby データベース・プラグインの機能をテストするための単純なコード

ここで、単純なプラグインを作成して、コア Derby プラグインの機能を実演してみることができます。それには Eclipse Plug-In Project ウィザードを使って、Hello World テンプレートに基づく sample_derby という名前の新規プロジェクトを作成してください (図 2 を参照)。

図 2. Eclipse Hello World プラグインの作成ウィザード
図 2. Eclipse Hello World プラグインの作成ウィザード
図 2. Eclipse Hello World プラグインの作成ウィザード

オリジナルの Hello World プラグインが作成するのは Sample Menu という名前の単純な Eclipse メニュー要素で、このメニューには Sample Action メニュー項目があります。ユーザーがこのメニュー項目をクリックすると、Hello World! ダイアログ・ボックスがポップアップ表示されます。このプラグインでは、Eclipse ツールバーからダイアログ・ボックスを呼び出すことも可能です。これを確認するには、plugin.xml ファイル・エディターのウィンドウ内で Run an Eclipse application リンクをクリックするか、あるいは Eclipse ツールバーの Run ボタンをクリックし、Eclipse application コンフィギュレーションを使用してダイアログ・ボックスを呼び出します。

新しく作成したプラグインに Derby サポートを追加するということは、プラグインが Derby Core Plug-in に依存するようにコンフィギュレーションを指定するということです。それには sample_derby プロジェクトで plugin.xml ファイルを開き、Dependencies タブの Required Plug-ins セクションで org.apache.derby.core への依存関係を選択します (図 3 を参照)。これが完了すると、プラグインが Derby クラスを使用できるようになります。

図 3. プラグインの依存関係エディター
図 3. プラグインの依存関係エディター
図 3. プラグインの依存関係エディター

単純な Derby データベースの操作方法を理解する方法として、ローカル・データベースの Records テーブルを対象とした単純なレコード・カウンターを提供するようにプラグインを拡張します。このテーブルには、データベース内のレコード数についての情報が含まれます。ボタンをクリックするとレコード数が 1 つ増加し、現在のレコード数を示すダイアログ・ボックスが表示されます。まず、Sample Action 用のクラスを定義する SampleAction.java ファイルを開いて、queryRecords という名前のメソッドを新規に作成してください。この時点で接続しているのは、既存のデータベースだけです。適切なデータベースが存在しない場合は、システムが新しいデータベースを作成して常に 0 を返します (リスト 1 を参照)。

リスト 1. Derby 初期化コード
public class SampleAction implements IWorkbenchWindowActionDelegate {
/* ...code skipped here... */

/** driver string. */
private static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
/** protocol string. */
private static final String PROTOCOL = "jdbc:derby:";
/** database name string. */
private static final String DATABASE = "sampleDB";

/** SQL script for creating Categories table. */
private static final String CREATE_TABLE = "CREATE TABLE Records" 
     + "("
     + "quantity int"
     + ")";

/* ...code skipped here... */

/**
* Connects to database, inserts one record into Records table 
* and then counts total records quantity in database.
* If database does not exist, then new database is created.  
*/
private int queryRecords()
        throws SQLException, IllegalAccessException, ClassNotFoundException,
        InstantiationException {

    Connection currentConnection = null;
    System.setProperty("derby.system.home",
        Sample_derbyPlugin.getDefault().getStateLocation().toFile().getAbsolutePath());
    Properties props = new Properties();

    try {
        Class.forName(DRIVER).newInstance();
        currentConnection = DriverManager.getConnection(PROTOCOL 
            + DATABASE, props);

    } catch (SQLException sqlException) {
        //trying to create database
        currentConnection = DriverManager.getConnection(PROTOCOL 
            + DATABASE + ";create=true", props);
        try {
            Statement s = currentConnection.createStatement();
            try {
                s.execute(CREATE_TABLE);
            } finally {
                s.close();
            }
            currentConnection.commit();
        } catch (SQLException ex) {
            currentConnection.close();
            throw ex;
        }
    }
    return 0;
}

Derby システム・ファイルの場所に対応するのは、システム・プロパティー derby.system.home です。リスト 1 では、このシステム・プロパティーはワークスペース・ディレクトリー内にあるプラグインのデータ・フォルダー .metadata/.plugins/sample_derby に設定されています。

クエリー関数が正常に接続を確立したことを検証するには、同じ Java ソース・ファイルに以下のコード (リスト 2) を追加して実行メソッドを変更します。

リスト 2. 情報ダイアログ・ボックスの表示
MessageDialog.openInformation(
window.getShell(),
"Sample_derby Plug-in",
"We have " + queryRecords() + " Records in the database");

queryRecords メソッドは例外をスローするため、try-catch 構文を使用してエラー・メッセージ・ダイアログを表示し、例外を処理する必要があることに注意してください。

Sample Action プログラムを呼び出すと、以下のように表示されます (図 4 を参照)。

図 4. 実行中のサンプル・アプリケーション
図 4. 実行中のサンプル・アプリケーション
図 4. 実行中のサンプル・アプリケーション

次に必要なのは、このアプリケーションに INSERT/SELECT クエリーを追加することです。リスト 3 に示すコードは単純なもので、新しいエントリーを Records テーブルに追加し、レコード数をカウントしてその結果を返します。Java ファイルの先頭に、以下の行を追加してください。

リスト 3. Derby クエリー宣言
/** SQL query that counts number of records in database    */
private static final String SELECT_RECORDS_QUERY = 
        "SELECT SUM(quantity) FROM Records";
    
/** SQL script that adds new record into database    */
private static final String INSERT_RECORDS_QUERY = 
        "INSERT INTO Records (quantity) VALUES(1)";

queryRecords メソッドの終わりには、以下のコードを追加します。

リスト 4. Derby クエリーの使用例
int result = 0;
try {
    Statement s = currentConnection.createStatement();
    try {
        s.execute(INSERT_RECORDS_QUERY);
        ResultSet rs = s.executeQuery(SELECT_RECORDS_QUERY);
        if (rs.next()) {
            result = rs.getInt(1);
        }
    } finally {
        s.close();
    }
    currentConnection.commit();
} finally {
    currentConnection.close();
}
return result;

Eclipse はデータベースとの接続を確立すると、Records テーブルに新しい行を 1 行挿入し、テーブル内のレコード数をカウントしてその数を返します。その結果、Sample Action をトリガーするたびにレコード数は増えていきます。このアプリケーションを何度か呼び出すと、図 5 のようなダイアログが表示されるはずです。

図 5. 実行中のサンプル・アプリケーション
図 5. 実行中のサンプル・アプリケーション
図 5. 実行中のサンプル・アプリケーション

Eclipse プラグイン内で内部 Derby データベースをどのように使用できるかを簡単に実演しました。今度は、複雑なアプリケーションでプラグインを使用する方法を見ていきましょう。

リソース索引付けプラグイン

リソース索引付け機能は、IDE にとって重要な機能です。CDT (C/C++ Development Tooling) Eclipse プラグインを調べてみると、その理由がわかります。このプラグインをインストールして、少数のソース・ファイルを持つ単純な C++ プロジェクトを作成し、#includes をいくつか追加してから自動補完機能を使用してみてください。小さなプロジェクトでも、自動補完のためのあらゆるバリエーションを検出するのに数秒かかることがわかるはずです。さらに、この操作はEclipse のすべてのリソースを使用するため、一時的なフリーズが発生します。

この記事には、そのまま使えるリソース索引付けアプリケーションがサンプルとして付属しています。このアプリケーションは、Eclipse ワークプレース内でプラグインが定義している特定の特性、Sample Nature を持つすべてのプロジェクト・リソース (ファイル) を監視します (「参考文献」を参照)。リソースに関する情報は Derby データベースに保管し、Resources View というビューを表示してユーザーがファイルを検索できるようにします。

このセクションでは、アプリケーションを作成するための主なステップを順を追って説明します。Eclipse プラグイン GUI の開発などの一般的なステップは省略し、プラグイン開発における Derby に焦点を絞ります。

接続プール・データ・ソース・マネージャー

Derby データベースには JDBC を介してアクセスするため、データベース接続の管理に Derby の ConnectionPoolDataSource インターフェース実装を使用するのは名案です。ConnectionPoolDataSource は、データベースを操作するたびに新しい接続をオープンしなくても済むように、常にデータベースに対して複数のオープン接続を維持するので、処理がスピードアップします。さらに、アプリケーションがデータベースに対して同時に複数の接続をオープンする場合の競合も ConnectionPoolDataSource によって回避できます。

使用するクラスは EmbeddedConnectionPoolDataSource です。これは Derby JDBC ドライバーに付属しています。リスト 5 では、PerUserPoolDataSource クラスのインスタンスを作成し、その接続プール・データ・ソースとして EmbeddedConnectionPoolDataSource クラスのインスタンスを設定しています。

リスト 5. Derby データ・ソースの初期化
* Datasource to use for connection.
*/
private static PerUserPoolDataSource datasource;

/**
* Initializes database and creates datasource instance for it.
*/
public static void initDatasource () {
    EmbeddedConnectionPoolDataSource connectionPoolDatasource;

    connectionPoolDatasource = new EmbeddedConnectionPoolDataSource(); 
    connectionPoolDatasource.setDatabaseName(
        ResourcesIndexerPlugin.getDefault().getStateLocation().
        toFile().getAbsolutePath() + "/resourcesDB");
    connectionPoolDatasource.setCreateDatabase("create");
        
    datasource = new PerUserPoolDataSource();
    datasource.setConnectionPoolDataSource(connectionPoolDatasource);
    datasource.setDefaultAutoCommit(false);
        
    try {
        Connection connection = datasource.getConnection();
        try {
            Statement statement = connection.createStatement();
            // searching for Resources table in database and 
            // if there is no one then initialize database
            try {
                statement.execute("SELECT 1 FROM  ");
            } catch (SQLException ex) {
                ResourcesDatabaseInitializer.initDatabase(connection);           
            } finally {
                statement.close();
            }
            connection.commit();
        } finally {
            connection.close();
        } catch (SQLException ex) {
            // Error handling here
        }
    }
}

「Derby データベース・プラグインの機能をテストするための単純なコード」セクションで説明したテスト・アプリケーションでは、derby.system.home システム・プロパティーを使って Derby システム・ファイルの場所を指定しました。一方、上記のコードでは、setDatabaseName メソッドがこの場所をデータベース名の一部として扱っています。データ・ソースの初期化が完了すると、リスト 5 に示したコードがデータベース内に Resources テーブルが存在するかどうかを調べ、存在しない場合はデータベース初期化コード ResourcesDatabaseInitializer を呼び出します。この例では、このデータベース初期化コードはデータベースを初期化するユーティリティー・クラスです。Eclipse プラグインの初期化中には initDatasource メソッドが呼び出されるため、データ・ソース変数は初期化されてからデータベースの操作に使用されることになります。

データベース操作層

リソース索引付けプラグインを作成するための 2 番目のステップは、データベース操作層を実装することです。この層は、情報の挿入、削除、問い合わせなどの操作を担当します。リスト 6 は、Resources データベースに新しいリソースを追加するメソッドの一例です。

リスト 6. データの操作
* Adds resource entry in database
* @param resource resource to add into database
* @throws SQLException if SQL error occurred
*/
public static final void addResource(ResourceEntity resource) throws SQLException {
    Connection connection = datasource.getConnection();
    try {
        PreparedStatement s = connection.prepareStatement(
                "INSERT INTO Resources (path, name, project) VALUES(?,?,?)");
        try {
            s.setString(1, resource.getResourcePath());
            s.setString(2, resource.getResourceName());
            s.setString(3, resource.getProjectName());
            s.execute();
        } finally {
            s.close();
        }
        connection.commit();
    } finally {
        connection.close();
    }
}

上記の例が操作するのは、基本的なデータベース構造と実に単純なクエリーです。実際のアプリケーションはこれより遥かに複雑なデータを操作するので、かなりのパフォーマンスを得るためには、アプリケーションが賢明に設計されたデータベース・スキーマと SQL クエリーを使用する必要があります。

ビルダーによるリソースの索引付け

リソースに索引を付けるための最善の方法は、ビルダーを使うことです。Eclipse では、ビルダーが特定のプロジェクト特性と関連付けられます。プロジェクト内で変更 (作成、削除、リソースの更新など) が行われるたびに、ビルダーによって変更が処理されます。ビルダーはまた、プロジェクト全体の完全なリビルドとクリーンといったタスクも処理します。

ビルダーのサポートを Eclipse プラグインに追加するには、Project Builder and Nature 拡張ウィザードを使用します。このウィザードは、ある特性とその特性に関連するビルダーを作成します。この記事付属のサンプル・アプリケーションでは、この特性の名前は Sample Nature となっています。プロジェクトの追加変更を処理するため、IResourceDeltaVisitor インターフェースを実装する必要があります (リスト 7 を参照)。

リスト 7. IResourceDeltaVisitor の実装例
public boolean visit(IResourceDelta delta) throws CoreException {
    IResource resource = delta.getResource();

    /* ...code skipped here... */

    switch (delta.getKind()) {
        case IResourceDelta.ADDED:
            DatabaseUtil.addResource(resource);
        break;
        case IResourceDelta.REMOVED:
            DatabaseUtil.removeResource(resource);
        break;
    }

    /* ...code skipped here... */

}

リスト 7 では、ワークスペースに対するリソースの追加と除去という 2 つの操作を処理しています。これは単なる一例なので、当然、これより複雑な操作を実装することも考えられます。

ビルダーが用意できたら、Sample Nature をプロジェクトに追加してプロジェクトのリソースに索引を付けます。この索引は、「データベース操作層」セクションで説明したそれぞれのメソッドを呼び出すことによって、Eclipse アプリケーション・コードのあらゆる部分で使用できます。

サンプル・アプリケーションのテスト

記事付属のサンプル・プラグイン・アプリケーションをテストするには、まず Eclipse (Derby プラグインもインストールされた状態) にインストールします。次に、ワークプレース内にある目的のプロジェクトを右クリックし、Add/Remove Sample Nature メニュー項目を使って Sample Nature をプロジェクトに関連付けます。これにより、ただちに監視対象のプロジェクトのすべてのリソースに索引が付けられます。

索引が付けられたファイルを検索するには、Resource View を使用します。最上位のメニュー・コマンドから Window > Select View > Other を選択し、Resources ビュー・グループにある Resources View を選択すると、このビューが表示されます。検索は各ファイル名の先頭によって実行されるので、図 6 のような表示になります。

図 6. 実行中のリソース索引付けプラグイン
図 6. 実行中のリソース索引付けプラグイン
図 6. 実行中のリソース索引付けプラグイン

Resource View に表示されたリソースにアクセスするには、リスト内の項目をダブルクリックします。このビューはワークプレースに変更が行われても自動的に更新されませんが、Views > Refresh を選択すると更新できます。

まとめ

Eclipse と Apache Derby は、どちらも今日の業界で知名度の高いオープン・ソース・プロジェクトです。Eclipse フレームワークでは、IDE アプリケーションをはじめ、さまざまな GUI アプリケーションを作成できます。一方 Apache Derby では、Java アプリケーション対応のローカル SQL データベースを作成できます。そしてこの記事で実演したように、Eclipse と Derby は簡単に併用することができます。

リソース索引付けプラグインは、Derby データベースを使用して開発する Eclipse プラグインの代表的な例です。Eclipse Builder フレームワークとともに使用すれば、リソース情報を SQL データベースに保管し、その情報を使ってクエリーを作成できます。Derby データベースは SQL クエリーを対象に最適化されるため、最大限のパフォーマンスでリソース索引にアクセスできます。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source, Information Management
ArticleID=249808
ArticleTitle=Apache Derby で Eclipse プラグインを開発する
publish-date=01162007