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

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

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

Ilya Platonov (ill@isg.axmor.com), Software Engineer and Developer, Axmor

Ilya Platonov は、ロシア・ノボシビルスクにある IBM Advanced Technology Solutions (ATS) Lab の顧問を務める Axmor Software のソフトウェア・エンジニアです。ノボシビルスク州立大学でコンピューター・サイエンスの修士号を取得しました。最近は、5 つを越える ATS プロジェクトにシステム・アーキテクトあるいはソフトウェア・エンジニアとして参加しています。



Artem Papkov (artem@us.ibm.com), IT Architect, IBM 

Artem Papkovは現在、IBMのClient Innovation Teamのソリューション・アーキテクトであり、顧客やビジネス・パートナーがSOAやWebサービスなど、新興技術を採用するための協力を行っています。1998年にコンピューター・サイエンスの修士としてBelarusian State University of Informatics and Radioelectronicsを卒業後、2000年にノースキャロライナ州Research Triangle ParkにあるIBMに入社しました。これまで経験した分野としては、新興技術を使用したマルチ階層ソリューションのソフトウェア開発や、アーキテクチャー設計、インターネット・ベース・ソリューションの統合などがあります。過去3年間は、顧客と緊密に協力しながら、IBMの戦略的統合技術としてのWebサービスと、統合手法としてのSOA採用促進を進めてきました。彼の連絡先はartem@us.ibm.comです。



Jim Smith (jamessmi@us.ibm.com), Senior IT Architect/Consultant, IBM 

Jim Smithは、ソフトウェア開発に18年以上の経験を持っています。最初の仕事は、カリフォルニア州LivermoreのSandia National Labsにおいて、無数の既存レガシー・コードを使っての高速データ収集システムと分散コンピューティング・システムの設計でした。その後、Java言語に関する深い経験と顧客対応スキルを持つ彼はEmerging Internet Technologiesチームに移動し、IBMの顧客に対してJavaソリューションを現実のものとすることに焦点を当てています。彼はまた、ソフトウェア・サービスと開発のための世界的な組織である、ATS(Advanced Technology Solutions)の設立者の1人です。ATSのミッションは、IBMや、開発研究所、ビジネス・パートナー、顧客などに対して、先進技術と軽量ビジネス・プロセスを開発し、改善し、普及させることによって、標準技術やIBM製品の迅速な採用、展開を図ることです。現在、この組織の運営をJimが行っています。彼の連絡先はjamessmi@us.ibm.comです。



Terry Finch (terryfin@us.ibm.com), IT Specialist, IBM

Terry Finch は Customer Innovation Team の IT スペシャリストとして、新興技術に関連する第一線のカスタマー・プロジェクトに取り組んでいます。2000年に入社して以来、IBM WebSphere® Portal ソフトウェア、IBM Lotus® Domino® ソフトウェア、Java テクノロジー、XML、Web サービス、リッチ・インターネット・アプリケーションなどに関わる多数のプロジェクトを成功裏に完了させています。最近では、Macromedia Flex、Laszlo、IBM Workplace Client Technologies (IWCT) などのリッチ・ユーザー・インターフェース、そして Ajax および QEDWiki などの Web 2.0 技術を重点に取り組んでいます。



2007年 1月 16日

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 プラグイン

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


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

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

図 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. プラグインの依存関係エディター

単純な 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. 実行中のサンプル・アプリケーション

次に必要なのは、このアプリケーションに 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. 実行中のサンプル・アプリケーション

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. 実行中のリソース索引付けプラグイン

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


まとめ

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

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


ダウンロード

内容ファイル名サイズ
Sample projects for this articlesamples.zip173KB

参考文献

学ぶために

製品や技術を入手するために

  • IBM ソフトウェアの試用版を使用して、次のオープン・ソース開発プロジェクトを革新してください。ダウンロード、あるいは DVD で入手できます。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


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