動的プラグインにより、Eclipse の実行中のインスタンスに対するプラグインの挿入および除去が可能となります。アンロード可能な再使用可能コンポーネントである動的プラグインを使用すると、プラグインの追加および除去を簡単に追跡できます。
動的プラグインは、アプリケーションのライフタイムの間存続するとは限りません。したがって、コンポーネントが除去されるときに、すべてを確実にクリーンアップすることが重要です。ワークベンチ上でリスナーがフックされて項目が登録されると、プラグインはシャットダウン後も存続するため、これらのプラグインは、クリーンアップが必要であることを認識していなければなりません。
アプリケーションのライフタイムの間、始動時に拡張ポイントのすべての実装を読み取るだけで十分であるという想定は間違っています。これは機能しません。リスナーがフックされるようにするか、または何もキャッシュに入れないようにして、レジストリーの変更が listen されるようにする必要があります。ワークベンチ内の項目は静的である必要はありません。これらは実際には一時的であり、いつでも除去される可能性があります。特定のビュー用のプラグインを作成する場合は、まずビューが存在していることを確認する必要があります。
プラグイン開発者は、利用する拡張をいつでも使用可能および除去可能にしておく必要があります。拡張を除去する場合は、拡張を表すすべての内部構造をクリーンアップし、拡張が駆動するすべての UI 成果物を除去することによって、拡張が除去されたことを確認する必要があります。拡張を使用する場合は、内部構造を補強して、可能であれば新規 UI 成果物を作成する必要があります。アプリケーションがレジストリーから読み取りを実行中で拡張を備えていると想定し、そのレコードを作成してロケーションを割り当てるとします。これが終結すると、クリーンアップが必要であると通知されます。さらに、リスナーは、新規項目の出現を知らせ、新規項目を作成します。
org.eclipse.core.runtime.dynamicHelpers.IExtensionTracker および関連したインターフェースは、プラグイン開発者が拡張の追加と除去を簡単に追跡し、そのようなアクションによって生成されたリソースを管理するためのメカニズムを提供します。
以下の例は、ウィジェットと呼ばれるプラグインに拡張ポイントが設けられていて、IExtensionTracker が使用されていると想定しています。内部に、ウィジェット拡張をカプセル化した WidgetDescriptors およびそれらを管理する WidgetRegistry があります。
public class WidgetRegistry implements IExtensionChangeHandler { public WidgetRegistry() { IExtensionTracker tracker = PlatformUI.getWorkbench() .getExtensionTracker();
IExtensionPoint point = Platform.getExtensionRegistry() .getExtensionPoint("my.plugin.namespace", "widget");
IExtension[] extensions = point.getExtensions();
// initial population
for (int i = 0; i < extensions.length; i++) { addExtension(tracker, extensions[i]);
} tracker
.registerHandler(this, tracker
.createExtensionPointFilter(point)); } public void addExtension(IExtensionTracker tracker, IExtension extension){ WidgetDescriptor descriptor = new WidgetDescriptor(extension); tracker.registerObject(extension, descriptor,
IExtensionTracker.REF_STRONG); addToInternalStructure(descriptor) } private void addToInternalStructure(WidgetDescriptor descriptor) { // registry specific logic } public void removeExtension(IExtension extension, Object[] objects) { for (int i = 0; i < objects.length; i++) { WidgetDescriptor descriptor = (WidgetDescriptor) objects[i];
removeFromInternalStructure(descriptor);
}
} private void removeFromInternalStructure(WidgetDescriptor descriptor) { // registry specific logic }
} public void dispose() { PlatformUI.getWorkbench() .getExtensionTracker().unregisterHandler(this)
} }
この例では、プラットフォーム UI は、ワークベンチのさまざまなレベルの IExtensionTracker インスタンスを提供しています。ワークベンチのライフタイムの間存続するオブジェクトを追跡する場合は、IWorkbench.getExtensionTracker() で提供されるトラッカーを使用する必要があります。 オブジェクトが特定のワークベンチのウィンドウまたはページに関連している場合は、IWorkbenchWindow.getExtensionTracker() または IWorkbenchPage.getExtensionTracker() で提供されるトラッカーを使用する必要があります。 例えば、ワークベンチは、ビュー・ディスクリプターをワークベンチ・レベルで追跡しますが、実際のビュー・インスタンスの追跡はワークベンチ・ページ・レベルで行います。IFilter インスタンスを IExtensionTracker.registerHandler() に提供することによって、ハンドラーを特定の拡張ポイントに対して登録できます。 ハンドラーは、IFilter オブジェクトと一致する拡張が追加または除去される場合にのみ呼び出されます。
拡張がランタイムに入ると、このメソッドが呼び出されます。これで、新規拡張を関連したモデルに組み込む機会がハンドラーに提供されます。このインターフェースに提供される IExtension に基づいて作成されたオブジェクトは、IExtensionTracker.registerObject() を介してトラッカーに対して登録する必要があります。 拡張がランタイムから出ると、このメソッドが呼び出されます。拡張に対して以前に登録されていたオブジェクトが引数として渡されます。次いで、ハンドラーは、必要に応じてオブジェクトをクリーンアップして廃棄します。レジストリーがリークしないよう、ハンドラーを登録抹消することをお勧めします。