すでに説明したように、プラグインは、専用のファイル拡張子を定義し、それらのファイル・タイプに対して専用の編集機能を提供するエディターを追加することができます。 リソースを編集 (またはビルド) する一連の作業中に、 プラグインはリソースにタグを付け、問題または他の情報をユーザーに通知することが必要な場合があります。リソース・マーカー・メカニズムは、このような情報の管理に使用します。
マーカーは、リソースに付ける黄色いスティッキー・ノートに似ています。マーカーに、問題に関する情報 (例えば、ロケーション、重大度) または実行すべきタスクを記録できます。 または、単純にブックマークとしてマーカーでロケーションを記録できます。
ユーザーは、リソース内のマーク付けされたロケーションに迅速にジャンプできます。ワークベンチ UI は、 エディターの端に、ブックマーク、ブレークポイント、タスク、および問題の表示をサポートします。 これらのマーカーは、「タスク」ビューまたは「ブックマーク」ビューなどのビューに、項目として表示することもできます。
プラットフォーム・リソース API は、マーカーの作成、マーカー値の設定、新規マーカー型によるプラットフォームの拡張を行うメソッドを定義します。 プラットフォームはマーカーを管理しますが、マーカーの作成、除去、および属性値を制御するのはプラグインです。
マーカーは、小さく軽いオブジェクトとして設計されます。1 つのプロジェクトには、数百、または数千のマーカーが存在する場合があります。 例えば、Java コンパイラーはマーカーを使用して、ソース・コードで検出したそれぞれの問題にフラグを立てます。
プラットフォームは、削除されるリソースに付けられているマーカーを除去します。 ただし、プラグインの役割は、存在しているリソースに適用されない不整合なマーカーを除去することです。
マーカーの操作は、リソースの操作に似ています。 マーカーはハンドル・オブジェクトです。 マーカー・ハンドルはリソースから取得できますが、exists() プロトコルを使用するか、または操作を行おうとするまで、 実際に存在するかどうかはわかりません。 マーカーが存在することが判明すると、そのマーカーに割り当てられている可能性のある名前付き属性を照会できます。
マーカーはプラットフォームによって所有および管理され、プラットフォームはマーカーを永続的にし、 リスナーにマーカーの追加、削除、または変更を通知します。 プラグインの役割は、必要なマーカーの作成、そのマーカーの属性変更、不要になった場合の除去です。
マーカーはコンストラクターを使用して直接作成されません。マーカーは、関連付けされたリソース上でファクトリー・メソッド (IResource.createMarker()) を使用して作成されます。
IMarker marker = file.createMarker(IMarker.TASK);
グローバル・スコープ (特定のリソースに関連付けされていない) を持つマーカーを作成するには、 リソースとしてワークスペース・ルート (IWorkspace.getRoot()) を使用することができます。
マーカーを削除するコードは簡単です。
try { marker.delete(); } catch (CoreException e) { // Something went wrong }
マーカーが削除される時は、そのマーカー・オブジェクト (ハンドル) は "不整合" になります。 プラグインは、マーカー・オブジェクトが依然として有効になるように、IMarker.exists() プロトコルを使用する必要があります。
マーカーは、リソースにそのマーカーを削除することを依頼して、バッチで削除できます。このメソッドは、多数のマーカーを同時に削除する場合、 または個々のマーカーの参照または ID が使用不可な場合に有効です。
int depth = IResource.DEPTH_INFINITE; try { resource.deleteMarkers(IMarker.PROBLEM, true, depth); } catch (CoreException e) { // something went wrong }
マーカーのグループを削除する場合は、IMarker.PROBLEM などの削除するマーカー型を指定するか、または null を指定してすべてのマーカーを削除します。2 番目の引数は、 サブタイプのマーカーを削除するかどうかを示します。 (サブタイプの解説は、新規マーカー型の定義で説明します。) depth 引数は、削除の深さをコントロールします。
IWorkspace.deleteMarkers(IMarker []) を使用してマーカーを削除することもできます。
マーカーについて、そのマーカーに関連付けされたリソース、ID (そのリソースに対する固有なもの)、およびそのマーカーの型を確認できます。汎用属性によって追加情報をアクセスすることもできます。
それぞれのマーカーの型には、そのマーカー型の作成者が命名規則を使用して定義した一連の特定の属性があります。 IMarker インターフェースは、 プラットフォームのマーカー型に対する標準属性名 (および該当するいくつかの値) を含む一連の定数を定義します。 以下のメソッドは、プラットフォーム定数を使用する属性を取り扱います。
IMarker marker = file.createMarker(IMarker.TASK); if (marker.exists()) { try { marker.setAttribute(IMarker.MESSAGE, "A sample marker message"); marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH); } catch (CoreException e) { // You need to handle the case where the marker no longer exists } }
属性は、一般的に名前および値の組み合わせで保持されています。名前は、ストリングで、値は、サポートされる値型 (ブール値、整数、ストリング) のうちの 1 つです。 値型の制限によって、プラットフォームは迅速かつ簡単にマーカーを永続的にします。
リソースは、そのリソースのマーカーおよびその子のマーカーを照会できます。例えば、 無限の深さのワークスペース・ルートの照会は、そのワークスペース内のすべてのマーカーを考慮します。
IMarker[] problems = null; int depth = IResource.DEPTH_INFINITE; try { problems = resource.findMarkers(IMarker.PROBLEM, true, depth); } catch (CoreException e) { // something went wrong }
findMarkers から戻される結果は、渡される引数によって異なります。 上記のコードの断片で、リソース上に現れる PROBLEM 型 のすべてのマーカー、およびそのすべての直接的、間接的な子孫を確認できます。
null をマーカー型として渡すと、 そのリソースに関連付けされたすべてのマーカー型が取得できます。2 番目の引数は、そのリソースの子を確認するかどうかを指定します。 depth 引数は、 リソースの子を確認する場合には、検索の深さをコントロールします。depth は、DEPTH_ZERO (指定されたリソースのみ)、DEPTH_ONE (そのリソースおよびそのリソースのすべての直接的な子リソース)、または DEPTH_INFINITE (そのリソース、およびそのすべての直接的、間接的子孫) のいずれかにできます。
プラットフォーム標準マーカー (タスク、問題、およびブックマーク) は、永続的です。 これは、これらのマーカーの状態が、ワークベンチのシャットダウンから始動まで保管されることを意味しています。 ただし、永続タイプのマーカーは、予約属性 transient を true に設定することによって、目的のものだけ選んで一時的なものにすることができます。
プラグインによって宣言された新規のマーカー型は、それらの型が永続的として宣言されない限り、永続的ではありません。
プラグインは、org.eclipse.core.resources.markers 拡張ポイントを使用して、 それらプラグイン独自のマーカー型を宣言できます。問題、タスク、およびブックマークの標準マーカー型は、 プラットフォームによって、リソース・プラグインのマークアップに宣言されます。
<extension id="problemmarker" point="org.eclipse.core.resources.markers" name="%problemName"> <super type="org.eclipse.core.resources.marker"/> <persistent value="true"/> <attribute name="severity"/> <attribute name="message"/> <attribute name="location"/> </extension> <extension id="taskmarker" point="org.eclipse.core.resources.markers" name="%taskName"> <super type="org.eclipse.core.resources.marker"/> <persistent value="true"/> <attribute name="priority"/> <attribute name="message"/> <attribute name="done"/> <attribute name="userEditable"/> </extension> <extension id="bookmark" point="org.eclipse.core.resources.markers" name="%bookmarkName"> <super type="org.eclipse.core.resources.marker"/> <persistent value="true"/> <attribute name="message"/> <attribute name="location"/> </extension>
新規マーカー型は、複数の階層を使用して、既存の型から派生します。新規マーカー型は、 すべての属性を、それら属性のスーパータイプから継承し、宣言の一部として定義されたすべての新規属性を追加します。これらはまた、そのスーパータイプのスーパータイプから属性を継承します。以下のマークアップは、仮想 com.example.markers プラグインに新しい種類のマーカーを定義します。
<extension id="mymarker" point="org.eclipse.core.resources.markers" /> <extension id="myproblem" point="org.eclipse.core.resources.markers"> <super type="org.eclipse.core.resources.problemmarker"/> <super type="com.example.markers.mymarker"/> <attribute name="myAttribute" /> <persistent value="true" /> </extension>
org.eclipse.core.resources.problemmarker の型は、実際には事前定義された型 (aka IMarker.PROBLEM) の 1 つであることに注意してください。
マーカー・スーパータイプの継承されない唯一の性質は、 そのマーカーのパーシスタンス・フラグです。 パーシスタンスのデフォルト値は false です。このため、 永続的であるべきすべてのマーカー型は、<persistent value="true"/> を指定する必要があります。
ユーザー・プラグイン・マニフェスト・ファイルに新規マーカー型を宣言すると、com.example.markers.myproblem マーカー型のインスタンスを作成でき、myAttribute 属性を自由に設定または取得できます。
新規属性を宣言することによって、(ユーザーのビューおよびエディター内の) 他の場所で使用する目的で、 データをマーカーに関連付けることができます。 特定の型のマーカーは、宣言されたすべての属性に対して値を持つ必要はありません。属性宣言は、 内容の制限よりも、命名規則の問題の解決が目的です (このため、どのユーザーも"メッセージ"を使用してマーカーの記述について議論します)。
public IMarker createMyMarker(IResource resource) { try { IMarker marker = resource.createMarker("com.example.markers.myproblem"); marker.setAttribute("myAttribute", "MYVALUE"); return marker; } catch (CoreException e) { // You need to handle the cases where attribute value is rejected } }
ユーザーは、プラットフォームのマーカー型の照会と同じ方法で、ユーザー独自のマーカー型の照会ができます。 次のメソッドは、指定されたターゲット・リソースおよびそのリソースのすべての子孫に関連付けされた、 すべての mymarkers を検出します。 このメソッドは、true が includeSubtypes 引数に対して渡されるため、 すべての myproblems も検出することに注意してください。
public IMarker[] findMyMarkers(IResource target) { String type = "com.example.markers.mymarker"; IMarker[] markers = target.findMarkers(type, true, IResource.DEPTH_INFINITE); }