すでに説明したように、プラグインは、専用のファイル拡張子を定義し、それらのファイル型に対して専用の編集機能を提供するエディターを追加することができます。 リソースを編集 (またはビルド) する一連の作業中に、 プラグインはリソースにタグを付け、問題または他の情報をユーザーに通知することが必要な場合があります。リソース・マーカー・メカニズムは、このような情報の管理に使用します。
マーカーは、リソースに付ける黄色いスティッキー・ノートに似ています。マーカーに、問題に関する情報 (たとえば、ロケーション、重大度) または実行すべきタスクを記録できます。 または、単純にブックマークとしてマーカーでロケーションを記録できます。
ユーザーは、リソース内のマーク付けされたロケーションに迅速にジャンプできます。ワークベンチ UI は、 エディターのと共に、ブックマーク、ブレークポイント、タスク、および問題の表示をサポートします。 これらのマーカーは、タスク・ビューまたはブックマーク・ビューなどのビューに、項目として表示することもできます。
プラットフォーム・リソース API は、マーカーの作成、マーカー値の設定、新規マーカー型によるプラットフォームの拡張を行うメソッドを定義します。 プラットフォームはマーカーを管理しますが、マーカーの作成、除去、および属性値をコントロールするのはプラグインです。
マーカーは、小さく軽いオブジェクトとして設計されます。1 つのプロジェクトには、数百、または数千のマーカーが存在する場合があります。 たとえば、Java コンパイラーはマーカーを使用して、ソース・コードで検出したそれぞれの問題にフラグを立てます。
プラットフォームは、削除されるリソースに付加されているマーカーを除去します。 ただし、プラグインの役割は、存在しているリソースに適用されない不整合なマーカーを除去することです。
マーカーの操作は、リソースの操作と同様です。 マーカーはハンドル・オブジェクトです。 リソースからマーカー・ハンドルを取得できます。ただし、取得したハンドルは、exists() プロトコルを使用するまで、またはそのハンドルを操作するまで実際に存在するかどうかわかりません。 マーカーが存在することが判明すると、そのマーカーが属するリソースの検出、 その ID の照会、そのマーカーに割り当てられている名前付き属性の照会ができます。
マーカーはプラットフォームによって所有および管理され、プラットフォームはマーカーを永続的にし、 リスナーにマーカーの追加、削除、または変更を通知します。 プラグインの役割は、必要なマーカーの作成、そのマーカーの属性変更、不要になった場合の除去です。
マーカーはコンストラクターを使用して直接作成されません。マーカーは、関連付けされたリソース上でファクトリー・メソッド (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 引き数は、削除の深さをコントロールします。
ユーザーは、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 resource doesn't exist
}
属性は、一般的に名前および値の組み合わせで保持されています。名前は、ストリングで、値は、サポートされる値型 (ブール値、整数、ストリング) のうちの 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 (そのリソース、およびそのすべての直接的、間接的子孫) のいずれかにできます。
プラットフォーム標準マーカー (タスク、問題、およびブックマーク) は、永続的です。これは、これらのマーカーの状態が、ワークベンチのシャットダウンから始動まで保管されることを意味しています。
プラグインによって宣言された新規のマーカー型は、それらの型が永続的として宣言されない限り、永続的ではありません。
プラグインは、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"/>
</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);
}