Eclipseプラグイン実践テクニック(6)

拡張ポイントを作成してレッツ、コントリビュート!


NTTデータ先端技術
竹添直樹
NTTデータ 基盤システム事業本部 岡本隆史
2007/2/13


今回の主な内容

 以前の連載「作って覚えるEclipseプラグイン」から足かけ1年半にわたってEclipseプラグイン開発のさまざまなトピックを取り上げてきた本連載ですが、いよいよ今回で最終回となります。

 これまでは主に、「ほかのプラグインによって提供されている拡張ポイントを使用する」方法について説明してきたわけですが、今回は「自分のプラグインを拡張ポイントによって拡張できるようにする」方法について解説したいと思います。

編集部注拡張ポイントそのものについて詳しく知りたい読者は、「Hello♪」を表示するだけのEclipseプラグインのコラム「拡張ポイントとは」をご参照ください。

 拡張ポイントで「Hello, World!!


まずは、拡張ポイントを追加する

 拡張ポイントはマニフェスト・エディタの「拡張ポイント」タブで作成できます。

図1 拡張ポイントの追加
図1 拡張ポイントの追加

 「追加」ボタンをクリックすると拡張ポイントを追加するためのダイアログが開くので、拡張ポイントIDと拡張ポイント名を入力します。「プラグインのID.ここで入力した拡張ポイントID」が実際の拡張ポイントのIDになります(例として、ここでは「[jp.sf.amateras.extension].[hello]」となります)。

 拡張ポイントを追加すると、schemaフォルダ内にexsdという拡張子を持つスキーマファイルが作成され、以下の図2のような拡張ポイント・スキーマ・エディタが開きます。拡張ポイントのスキーマはXMLスキーマのサブセットで定義するのですが、このエディタによってグラフィカルにスキーマを編集できます。

図2 拡張ポイント・スキーマ・エディタ
図2 拡張ポイント・スキーマ・エディタ


拡張ポイントのスキーマ定義
はどうなっているか?

 まずは簡単な例として、メッセージをコントリビュートすると、その文字列をダイアログで表示する、という簡単な拡張ポイントを考えてみます。

リスト1 シンプルな拡張ポイント
<extension point="jp.sf.amateras.extension.hello">
    <hello message="Hello, World!!"/>
    <hello message="Hello, Eclipse!!"/>
</extension>

図3 コントリビュートされたメッセージを表示
図3 コントリビュートされたメッセージを表示

 拡張ポイントのスキーマは「定義」タブで編集できます。以下のようにhello要素と、message属性を追加します。またmessage属性はrequiredにしておきましょう。

図4 hello要素とmessage属性を追加
図4 hello要素とmessage属性を追加

 次に、extension要素を右クリックし「新規」→「コンポジター」→「sequence」を選択し、シーケンスを追加します。さらに、追加したシーケンスを右クリックし、「新規」→「参照」→「hello」で先ほど作成したhello要素への参照を追加します。

  hello要素は任意の数を記述できるようにしたいので、最大発生数のアンバウンドにチェックを入れておきましょう。これでextension要素の配下にhello要素を記述できるようになります。

図5 シーケンスを追加
図5 シーケンスを追加

 このときのexsd ファイルのスキーマ定義は以下のようになります(実際のexsdファイルには、このほかにも拡張ポイント・スキーマ・エディタで入力したドキュメンテーションが含まれます)。

リスト2 hello.exsd
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="jp.sf.amateras.extension">



<element name="extension">
    <complexType>
        <sequence>
            <element ref="hello"
                     minOccurs="1"
                     maxOccurs="unbounded"/>
        </sequence>
        <attribute name="point" type="string" use="required">
            <annotation>
                <documentation>
                </documentation>
            </annotation>
        </attribute>
        <attribute name="id" type="string">
            <annotation>
                <documentation>
                </documentation>
            </annotation>
        </attribute>
        <attribute name="name" type="string">
            <annotation>
                <documentation>
                </documentation>
                <appInfo>
                    <meta.attribute translatable="true"/>
                </appInfo>
            </annotation>
        </attribute>
    </complexType>
</element>

<element name="hello">
    <complexType>
        <attribute name="message" type="string" use="required">
            <annotation>
                <documentation>
                </documentation>
            </annotation>
        </attribute>
    </complexType>
</element>



</schema>


コントリビュートされた内容を読み取る

 次に、拡張ポイントでコントリビュートされた内容を読み取って処理を行う部分を実装します。コントリビュートされた拡張情報はorg.eclipse.core.runtime.Platformから取得できるIExtensionRegistryを使用することで読み込めます。今回は以下のようにアクションで読み込むようにしてみます。

リスト3 コントリビュートされた拡張を読み込む
public class SampleAction
implements IWorkbenchWindowActionDelegate {

    private IWorkbenchWindow window;

     public void run(IAction action) {
        StringBuffer sb = new StringBuffer();
        IExtensionRegistry registry
            = Platform.getExtensionRegistry();

        // 拡張ポイントを取得
        IExtensionPoint point = registry.getExtensionPoint(
            Activator.getDefault().getBundle()
                .getSymbolicName() + ".hello");

        // コントリビュートされた拡張を取得
        IExtension[] extensions = point.getExtensions();
        
        for(int i=0;i<extensions.length;i++){
            
            IConfigurationElement[] elements                          
            = extensions[i].getConfigurationElements();
            
            for(int j=0;j<elements.length;j++){
                
                // 要素名がhelloだった場合、message属性の内容を追加
                if(elements[j].getName().equals("hello")){
                    String message
                        = elements[j].getAttribute("message");
                    sb.append(message).append("\n");
                }
            }
        }
        // コントリビュートされたメッセージをダイアログで表示
        MessageDialog.openInformation(shell
            ,"コントリビュートされたメッセージ",sb.toString());
    }

    public void init(IWorkbenchWindow window) {
        this.window = window;
    }



}

 実際には、プラグインの各機能の実装コードで直接拡張を読み取るのではなく、拡張情報読み込み用のクラスを用意するなどして1カ所にまとめておくとよいでしょう。

 
1/2

 INDEX
第6回 拡張ポイントを作成してレッツ、コントリビュート!
Page1
拡張ポイントで「Hello, World!!」
  まずは、拡張ポイントを追加する
  拡張ポイントのスキーマ定義はどうなっているか?
  コントリビュートされた内容を読み取る
  Page2
Javaオブジェクトをコントリビュートするには?
プラグイン内のリソースもコントリビュートできる
最後に…「Eclipse開発の効率をアップするために」



Java Solution全記事一覧



Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間