ハンドラー

org.eclipse.ui.handlers

3.1

ハンドラー拡張ポイントは、Eclipse 3.0 で定義された試験的な handlerSubmission 要素の推敲です。ハンドラーは、特定の時点でのコマンドの振る舞いです。コマンドには、関連するゼロまたはそれ以上のハンドラーがあります。ただし、コマンドには、任意の時点で、アクティブ・ハンドラーがない場合と、アクティブ・ハンドラーが 1 つある場合があります。アクティブ・ハンドラーは、コマンドの振る舞いを現在実行しているハンドラーです。これは、アクション・ハンドラーおよび再ターゲット可能なアクションの概念に非常によく似ています。

ハンドラー拡張ポイントにより、プラグイン開発者は、特定の条件下でアクティブおよび/または使用可能になるハンドラーを指定することができます。ハンドラーが非アクティブの場合、ハンドラーに対する振る舞いを委譲するコマンドはありません。ハンドラーが使用不可の場合、ハンドラーは実行を要求されません。つまり、ハンドラーの実行はブロックされています。条件は、3.0 で追加される式言語機能を使用して定義されます。activeWhen および enabledWhen 文節を使用して表します。

ワークベンチでは、これらの式で使用する変数がいくつか提供されています。サポートされる変数は、アクティブ・コンテキスト、アクティブ・エディター、アクティブ・パーツおよび現在の選択です。この初期設計ではサポートされていなくても、それ以外の変数を追加したり、プラグイン開発者がそれ以外の変数を提供したりすることが容易に行えます。

条件が指定されていないハンドラーが、デフォルトのハンドラーです。デフォルトのハンドラーは、すべての条件を満たすハンドラーがない場合にのみ、アクティブになります。条件を満たすハンドラーが 2 つある場合、条件が比較されます。条件がより特定されているか、またはよりローカルであるハンドラーが選択されます。この選択のために、条件により参照される変数が調べられます。最も特定の変数を参照する条件が「勝利」します。特定性の順序 (特定性の低い方から高い方へ) は、org.eclipse.ui.ISources で定義されています。

それでも競合が解決しない場合は、アクティブなハンドラーが存在しないことになります。特定のトレース・オプションがオンになっている場合、これにより、ログにメッセージが書き込まれます。デフォルトのハンドラーが 2 つある場合にも、競合が発生することがあります。プラグイン開発者および統合テスターの責任において、このようにならないようにしてください。これらの条件は、不要なプラグイン・ロードを回避するために使用されます。これらのハンドラー定義は、プロキシーによりラップされます。プロキシーが基礎ハンドラーをロードするには、プロキシーの条件が適格であってアクティブになること、およびプロキシーによる委譲が必要なことをコマンドによって行うこと (例えば、execute()) の 2 つが必要です。

<!ELEMENT extension (handler*)>

<!ATTLIST extension

point CDATA #REQUIRED

id    CDATA #IMPLIED

name  CDATA #IMPLIED>


<!ELEMENT handler (activeWhen? , class? , enabledWhen?)>

<!ATTLIST handler

commandId     CDATA #REQUIRED

class         CDATA #IMPLIED

helpContextId CDATA #IMPLIED>


<!ELEMENT activeWhen (not | and | or | instanceof | test | systemTest | equals | count | with | resolve | adapt | iterate)>



<!ELEMENT enabledWhen (not | and | or | instanceof | test | systemTest | equals | count | with | resolve | adapt | iterate)>



<!ELEMENT class (parameter*)>

<!ATTLIST class

class CDATA #IMPLIED>


<!ELEMENT parameter EMPTY>

<!ATTLIST parameter

name  CDATA #REQUIRED

value CDATA #REQUIRED>


<!ELEMENT enablement (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

汎用ルート要素です。 この要素を拡張ポイントの内部で使用すると、enablement 式を定義できます。 enablement 式の子は、AND 演算子を使用して結合されます。



<!ELEMENT not (not | and | or | instanceof | test | systemTest | equals | count | with | resolve | adapt | iterate)>

この要素は、サブ要素式を評価した結果に対する NOT 演算を表します。



<!ELEMENT and (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

この要素は、サブ要素式すべてを評価した結果に対する AND 演算を表します。



<!ELEMENT or (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

この要素は、サブ要素式すべてを評価した結果に対する OR 演算を表します。



<!ELEMENT instanceof EMPTY>

<!ATTLIST instanceof

value CDATA #REQUIRED>

この要素は、フォーカスされているオブジェクトの instanceof 検査を実行するために使用されます。 オブジェクトの型が、属性値で指定されている型のサブタイプの場合、この式は EvaluationResult.TRUE を戻します。これ以外の場合は、EvaluationResult.FALSE を戻します。



<!ELEMENT test EMPTY>

<!ATTLIST test

property CDATA #REQUIRED

args     CDATA #IMPLIED

value    CDATA #IMPLIED>

この要素は、フォーカスされているオブジェクトのプロパティー状態を評価するために使用されます。 テスト可能なプロパティーのセットは、プロパティー・テスターの拡張ポイントを使用して拡張することができます。 実際のテストを実行するプロパティー・テスターがまだロードされていない場合、test 式は EvaluationResult.NOT_LOADED を戻します。



<!ELEMENT systemTest EMPTY>

<!ATTLIST systemTest

property CDATA #REQUIRED

value    CDATA #REQUIRED>

System.getProperty メソッドを呼び出してシステム・プロパティーをテストし、その結果を、 value 属性によって指定された値と比べてください。



<!ELEMENT equals EMPTY>

<!ATTLIST equals

value CDATA #REQUIRED>

この要素は、フォーカスされているオブジェクトの等号検査を実行するために使用されます。 オブジェクトが、属性値によって提供された値と等しい場合、この式は EvaluationResult.TRUE を戻します。 これ以外の場合は、EvaluationResult.FALSE を戻します。



<!ELEMENT count EMPTY>

<!ATTLIST count

value CDATA #REQUIRED>

この要素は、コレクション内の要素の数をテストするために使用されます。



<!ELEMENT with (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST with

variable CDATA #REQUIRED>

この要素は、すべての子要素がインスペクション対象であるオブジェクトを、指定の変数で参照されているオブジェクトに変更します。 変数が解決できない場合、式は、評価時に ExpressionException をスローします。 with 式の子は、AND 演算子を使用して結合されます。



<!ELEMENT resolve (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST resolve

variable CDATA #REQUIRED

args     CDATA #IMPLIED>

この要素は、すべての子要素がインスペクション対象であるオブジェクトを、指定の変数で参照されているオブジェクトに変更します。 変数が解決できない場合、式は、評価時に ExpressionException をスローします。 with 式の子は、AND 演算子を使用して結合されます。



<!ELEMENT adapt (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST adapt

type CDATA #REQUIRED>

この要素は、フォーカスされているオブジェクトを、属性型で指定されている型に適合させるために使用されます。 アダプターまたは参照される型がまだロードされていない場合、式は「ロードされていない」を戻します。 型名が全く存在しない場合、評価中に ExpressionException がスローされます。 adapt 式の子は、AND 演算子を使用して結合されます。



<!ELEMENT iterate (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST iterate

operator (or|and) >

この要素は、java.util.Collection 型の変数を繰り返すために使用されます。 フォーカスされているオブジェクトの型が java.util.Collection ではない場合、式の評価時に ExpressionException がスローされます。



<extension point=

"org.eclipse.ui.handlers"

>

<handler commandId=

"commandId"

class=

"org.eclipse.compare.Command"

>

<activeWhen>

<with variable=

"selection"

>

<count value=

"1"

/>

<iterate operator=

"and"

>

<adapt type=

"IResource"

/>

</iterate>

</with>

</activeWhen>

</handler>

</extension>

さらにプラグインをロードすることを回避するため、ハンドラーを使用可能にする時期を指定することができます。プロキシーによりハンドラーがロードされていない場合は、ハンドラーが使用可能かどうかを判別するため、式構文が使用されます。プロキシーによりハンドラーがロードされている場合は、最初に、式構文が参照されます。式構文が真であると評価された場合、ハンドラーが使用可能かどうかが問われます。(これは、式構文とハンドラー使用可能状態との短縮されたブール「and」演算命令です。)

<extension point=

"org.eclipse.ui.handlers"

>

<handler commandId=

"commandId"

class=

"org.eclipse.Handler"

>

<enabledWhen>

<with variable=

"context"

>

<property id=

"id"

value=

"debugging"

/>

</with>

</enabledWhen>

</handler>

</extension>

すべてのハンドラーでは org.eclipse.core.commands.IHandler が実装されます。ワークベンチ内で、org.eclipse.ui.handlers.IHandlerService インターフェースを使用して、ハンドラーをアクティブおよび非アクティブにすることができます。IWorkbench 自体など、サポートするワークベンチ・オブジェクトからこのインターフェースを取得できます。サービスを取得するには、IWorkbench.getAdapter(IHandlerService.class) などを呼び出します。

ワークベンチの既存のコードを使用してハンドラーをアクティブおよび非アクティブにすることもできます。これは、以下に示す既存のメカニズムで実行されます。このメカニズムは、メニューまたはツールバーを提供するアクションを使用するクライアントで役立ちます。

 IWorkbenchPartSite mySite;
 IAction myAction;
 
 myAction.setActionDefinitionId(commandId);
 IKeyBindingService service = mySite.getKeyBindingService();
 service.registerAction(myAction);