基本的なカスタマイズ > ユーザーインタフェースのカスタマイズ > UI の情報の表示 > UI の検証 > 手順 - 事前検証 > 検証フィルタの実装
  
検証フィルタの実装
ソリューションベースと役割ベースのチェックにパスしたとします。事前検証アクティビティを実行するとき、次に検証サービスが行うのは、どのフィルタを UI コンポーネントに適用するかを決定することです。前述したとおり、通常の検証フィルタには複数の UI コンポーネントに適用される事前検証ロジックが含まれます。このため、このロジックを複数のバリデータに複製する代わりに、単一フィルタを作成して、ロジックを個別に UI コンポーネントに割り当てたり、すべての UI コンポーネントに割り当てたりすることができます。
フィルタタイプの選択 - 単純またはユニバーサル
フィルタを実装するときに最初に決めることは、シンプルフィルタとユニバーサルフィルタのどちらのフィルタにするかです。これを決めるには、フィルタロジックがグローバルな性質のものか、比較的少数の操作に適用するかを考えてください。
ロジックがほとんどの操作に適用される場合は、ユニバーサルフィルタの作成が適しています。この場合、フィルタはすべての操作に適用されます。ただし、操作はいつでもフィルタの "例外" と設定することができます。
フィルタロジックが少数の操作サブセットに適用される場合は、シンプルフィルタの作成が適しています。この場合、このフィルタを適用する操作があれば、個別に設定する必要があります。
実装するフィルタのタイプがわからない場合、最初はシンプルフィルタを使用し、必要に応じて後からユニバーサルフィルタに変換するのが簡単です。一点注意すべきことは、現在のところ、属性に適用するシンプルフィルタの設定も、ユニバーサルフィルタを無視する属性の設定もサポートされていないことです。このため、属性に適用するフィルタロジックがある場合は、ユニバーサルフィルタしか選択できません。ユニバーサルフィルタは、対象を問わずすべての属性に常に適用されるので、この点には注意してください。
シンプルフィルタの実装
シンプルフィルタを実装する場合は、com.ptc.core.ui.validation.DefaultSimpleValidationFilter を拡張するクラスを作成する必要があります。次に、preValidateAction() メソッドをオーバーライドして検証ロジックを含め、検証ステータスを返します。
以下のクラススケルトンは、コンテキストオブジェクトが削除と示されている場合に、操作を非表示にするシンプルフィルタの例です。
public class MarkedForDeleteFilter extends
DefaultSimpleValidationFilter{
@Override
public UIValidationStatus preValidateAction(UIValidationKey key,
UIValidationCriteria criteria){
// ENABLE by default
UIValidationStatus status = UIValidationStatus.ENABLED;
WTReference contextObj = criteria.getContextObject();
if (/*contextObj.isMarkedForDelete() == */ true){
status = UIValidationStatus.HIDDEN;
}
return status;
)
)
ユニバーサルフィルタの実装
ユニバーサルフィルタは、シンプルフィルタとまったく同じ方法で実装します。違いは 1 つだけです。ユニバーサルフィルタを実装する場合、com.ptc.core.ui.validation.DefaultUniversalValidationFilter を拡張する必要があります。その他の実装方法は、シンプルフィルタとまったく同じです。
シンプルフィルタの例をユニバーサルフィルタとして実装するとします。ユニバーサルフィルタのクラススケルトンは以下のようになります。
public class MarkedForDeleteFilter extends
DefaultUniversalValidationFilter{
@Override
public UIValidationStatus preValidateAction(UIValidationKey key,
UIValidationCriteria criteria){
// ENABLE by default
UIValidationStatus status = UIValidationStatus.ENABLED;
WTReference contextObj = criteria.getContextObject();
if (/*contextObj.isMarkedForDelete() == */ true){
status = UIValidationStatus.HIDDEN;
}
return status;
}
}
フィルタの登録
フィルタを作成した後の次のステップは、それを登録することです。
実装するフィルタのタイプ (ユニバーサルまたは単純) に応じて、フィルタの登録方法が異なります。レジストリにセレクタを設定する場合は、フィルタクラス名の最初の文字を小文字に置換し、"filter" サフィックスを取り除くという規則を使用します (たとえば、"MarkedForDeleteFilter" のセレクタは "markedForDelete" となります)。詳細は以下のとおりです。
ユニバーサルフィルタを登録するには、*service.proeprties.xconf に次のようなエントリを作成します。
<Service context="default"
name="com.ptc.core.ui.validation.UniversalValidationFilter">
<Option
serviceClass="com.ptc.windchill.enterprise.markedfordelete.validat
ors.MarkedForDeleteFilter"
selector="markedForDelete" requestor="null" />
</Service>
When registering a simple filter, the only difference is the name
attribute of the Service element:
<Service context="default"
name="com.ptc.core.ui.validation.SimpleValidationFilter">
<Option
serviceClass="com.ptc.windchill.enterprise.somepackage.validators.
MarkedForDeleteFilter"
selector="markedForDelete" requestor="null" />
</Service>
操作のフィルタへの関連付けと関連付け解除
フィルタを作成し、登録した後、最後に行うのは、操作とシンプルフィルタとの関連付け、または操作とユニバーサルフィルタとの関連付け解除です。これは、*actions.xml で行います。
ユニバーサルフィルタからの操作の関連付け解除
特定の操作にグローバルフィルタを適用したくない場合は、除外する操作を*acitons.xml に入れ、それを更新して、以下のように excludeFilter エレメントを含める必要があります。
<objecttype name="navigation" class=""
resourceBundle="com.ptc.core.ui.navigationRB">
<action name="home" renderType="GENERAL">
<command class="netmarkets"
method="servlet/Navigation?tab=home" windowType="page"/>
<excludeFilter name="markedForDelete" />
</action>
<action name="program" renderType="GENERAL">
<command class="netmarkets"
method="servlet/Navigation?tab=program"windowType="page"/>
<excludeFilter name="markedForDelete" />
</action>
<action name="product" renderType="GENERAL">
<command class="netmarkets"
method="servlet/Navigation?tab=product" windowType="page"/>
<excludeFilter name="markedForDelete" />
</action>
...
* 
excludeFilter エレメントの name 属性は、*service.properties.xconf へのフィルタの登録に使用した selector と対応する必要があります。
操作のシンプルフィルタへの関連付け
(仮定で) 問題レポートが特定のステータスである場合に操作を無効にするシンプルフィルタを ProblemReportStatusFilter という名前で作成し、登録した ("problemReportStatus" セレクタを使用して登録した) とします。また、それを少数の操作に適用するとします。フィルタを適用する操作は *actions.xml に入っているので、それを修正して、以下のように includeFilter エレメントを含めます。
<objecttype name="problemReport" class="wt.change2.WTChangeIssue"
resourceBundle="com.ptc.windchill.enterprise.change2.changeManagem
entActionsRB">
<action name="create" >
<command class=…/>
<includeFilter name="problemReportStatus" />
</action>
<action name="edit" >
<command class=…/>
<includeFilter name="problemReportStatus" />
</action>
<action name="editModifyContentOnly"
id="editModifyContentOnly">
<command class="…/>
<includeFilter name="problemReportStatus" />
</action>
...
* 
この場合も、includeFilter エレメントの name 属性は、*service.properties.xconf へのフィルタの登録に使用したセレクタと対応する必要があります。
同一操作に対する複数フィルタの追加/除外
理論的には、操作は関連付けを解除された任意の数のユニバーサルフィルタと関連付けられた任意の数のシンプルフィルタを持つことができます。必要な数の includeFilter と excludeFilter エレメントを *actions.xml に追加するだけです。
以下に例を示します。
<action name="removeChangeTask" renderType="GENERAL" ajax="row">
<command onClick="removeChangeTask(event)"
windowType="no_content" />
<includeFilter name="problemReportStatus />
<excludeFilter name="markedForDelete" />
<includeFilter name="someSimpleFilter" />
<excludeFilter name="someUniversalFilter" />
...
</action>
* 
includeFilter と excludeFilter エレメントの順序は不同です。フィルタが呼び出される順序に影響することもありません。
操作モデルのフィルタへの関連付けと関連付け解除
フィルタを作成し、登録した後で、操作モデルとシンプルフィルタを関連付けたり、操作モデルとユニバーサルフィルタとの関連付けを解除したりすることもできます。これは *actionModels.xml で行います。
ユニバーサルフィルタからの操作モデルの関連付け解除
特定の操作モデルにグローバルフィルタを適用したくない場合は、除外する操作モデルを *actionModels.xml に入れ、それを更新して、以下のように excludeFilter エレメントを含める必要があります。
<model name="CustEx_default_myTab">
<action name="CustEx_simpleTable1" type="object" />
<action name="CustEx_simpleTable2" type="object" />
<action name="CustEx_simpleTable3" type="object" />
<excludeFilter name=" someUniversalFilter " />
</model>
* 
excludeFilter エレメントのname 属性は、*service.properties.xconf でフィルタを登録するのに利用される selector に対応します。
操作モデルのシンプルフィルタへの関連付け
(仮定で) シンプルフィルタを ProblemReportStatusFilter という名前で作成して登録 ("problemReportStatus" セレクタを使用して登録) し、これをいくつかの操作モデルに適用するとします。フィルタを適用する操作モデルは *actionModels.xml に入っているので、それを修正して、以下のように includeFilter エレメントを含めます。
<model name="CustEx_default_myTab">
<action name="CustEx_simpleTable1" type="object" />
<action name="CustEx_simpleTable2" type="object" />
<action name="CustEx_simpleTable3" type="object" />
<includeFilter name="testFilter" />
</model>
* 
includeFilter エレメントのname 属性は、*service.properties.xconf でフィルタを登録するのに利用される selector に対応します。
同一操作モデルに対する複数フィルタの追加/除外
理論的には、操作は関連付けを解除された任意の数のユニバーサルフィルタと関連付けられた任意の数のシンプルフィルタを持つことができます。必要な数の includeFilter および excludeFilter エレメントを *actionModels.xml に追加するだけです。
例:
<model name="CustEx_default_myTab">
<action name="CustEx_simpleTable1" type="object" />
<action name="CustEx_simpleTable2" type="object" />
<action name="CustEx_simpleTable3" type="object" />
<includeFilter name="problemReportStatus />
<excludeFilter name="markedForDelete" />
<includeFilter name="someSimpleFilter" />
<excludeFilter name="someUniversalFilter" />
...
</model>
* 
includeFilter および excludeFilterelements エレメントの順序は不同です。フィルタが呼び出される順序に影響することもありません。