|
Eclipseのプラグインでは拡張ポイントに各自のプラグインを追加していく方式になっており、自分でも拡張ポイントを定義することが出来る。
他の人がその拡張ポイントに対するプラグインを作ると、(両方のプラグインが入っているEclipseでは)自分のプラグインからそのプラグインを呼び出せる。
拡張ポイントを定義する際には、まず処理のインターフェース(クラス)を作る。
他人はそのインターフェース(クラス)を実装(継承)することになる。
そして、拡張ポイントの宣言を作成する(plugin.xmlを記述する)。
拡張ポイントのextensionの書き方(スキーマ)を定義するexsdファイルも併せて作成する。
呼び出す(実装される)クラス(インターフェース)を作成する。
package com.example;
public abstract ExampleExtension {
public abstract String getValue();
}
plugin.xmlのマニフェストエディターで拡張ポイントタブを選択し、「Add」ボタンで拡張ポイントを追加する。
| 項目 | 例 | 説明 |
|---|---|---|
| Extension Point ID | exampleExtension |
拡張ポイントのID。 |
| Extension Point Name | extension example |
拡張ポイントの名前。 |
| Extension Point Schema | schema/exampleExtension.exsd |
スキーマファイルのファイル名。拡張ポイントIDを入れると自動的に入力される。 |
| Edit extension point schema when done | チェックを付けておくと、完了ボタンを押した後でスキーマファイルのエディターが開く。 |
スキーマファイルは、デフォルトでは「extension」要素だけ定義されている。
(extension要素にはpoint・id・name属性が定義されている)
今回の例では呼び出すクラスの定義を行いたいので、classpathという要素を追加し、classという属性を定義してみる。
| 項目 | 例 | 備考 |
|---|---|---|
| Name | classpath |
要素名 |
| Description | exampleExtension |
要素の説明 |
| 項目 | 例 | 備考 |
|---|---|---|
| Name | class |
属性名 |
| Deprecated | false |
非推奨かどうか |
| Use | required |
必須かどうか |
| Type | java |
属性値の型 |
| Extends |
com.example.ExampleExtension |
属性値の親クラス。 拡張するプラグインでは、このクラスを継承しているクラスのみ指定可能になる。 |
| Implements | 属性値のインターフェース(今回は未使用) |
| 項目 | 例 | 備考 |
|---|---|---|
| Min Occurrences | 0 |
子要素の最小の個数。 |
| Max Occurences | Unbounded |
子要素の最大の個数。Unboundedにすると無限。 |
| DTD Approximation | (classpath)* |
この項目は直接は入力不可能。他の項目から自動的に生成される。 デフォルトでは「EMPTY」となっている。 左側の一覧でSequenceを選択し、右クリックで「New」→「classpath」を選択するとclasspathが入力される。 |
Sequenceというのは、要素内に子要素が並ぶ(順番に現れる)ことを意味していると思われる。
最小が0で最大が無限だと「(classpath)*」、最小が1だと「(classpath)+」になる。
Sequenceの他にChoiceというものもある。
Sequenceの下にさらに別のSequenceやChoiceを入れられる。
実際のプラグイン(plugin.xml)に設定された値をロードしてキャッシュするクラスを用意しておくと便利。
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform;
public class ExtensionLoader {
private static final String EXAMPLE_EXTENSION_POINT_ID = Activator.PLUGIN_ID + ".exampleExtension"; //拡張ポイントID
private List<ExampleExtension> list;
public List<ExampleExtension> getExampleExtensions() {
if (list != null) {
return list;
}
IExtensionRegistry registory = Platform.getExtensionRegistry();
IExtensionPoint point = registory.getExtensionPoint(EXAMPLE_EXTENSION_POINT_ID);
if (point == null) {
throw new IllegalStateException(EXAMPLE_EXTENSION_POINT_ID);
}
list = new ArrayList<ExampleExtension>();
for (IExtension extension : point.getExtensions()) {
for (IConfigurationElement element : extension.getConfigurationElements()) {
try {
Object obj = element.createExecutableExtension("class"); //class属性
if (obj instanceof ExampleExtension) {
list.add((ExampleExtension) obj);
}
} catch (CoreException e) {
Activator.getDefault().getLog().log(e.getStatus());
}
}
}
return list;
}
}
このExtensionLoaderをActivatorクラスから取得できるようにしておく。
public class Activator extends AbstractUIPlugin {
〜
private ExtensionLoader extensionLoader;
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
this.extensionLoader = new ExtensionLoader();
}
public static ExtensionLoader getExtensionLoader() {
return getDefault().extensionLoader;
}
}
List<ExampleExtension> list = Activator.getExtensionLoader().getExampleExtensions();
for (ExampleExtension example : list) {
String value = example.getValue();
〜
}
拡張する側(呼ばれる側)は、普通のプラグインと同様。
<extension
point="com.example.examplePlugin.exampleExtension">
<classpath
class="com.example.Example1">
</classpath>
<classpath
class="com.example.Example2">
</classpath>
</extension>
public class Example1 extends ExampleExtension {
@Override
public String getValue() {
return "example1";
}
}