例: Hello-World
例として、タイプ認識型の Hello-World Webject 代理を新規作成する手順を示します。この Webject は入力グループを元に出力グループを作成し、オプションで "Hello World" というメッセージを java.io.PrintWriter に出力します。
ステップ 1: 新規 Webject 代理の作成
この Hello-World Webject は、実際に Windchill ビジネスオブジェクトと対話するわけではありません。また、Windchill アダプタベースクラスが提供するコンビニエンスメソッドを一切使用しません。したがって、com.ptc.core.adapter.server.impl.TypeAwareWebjectDelegate を実装する必要があります。
|
例をよりよく理解するため、ソースを一通り読むことをお勧めします。
Webject のソースは以下の場所にあります。
<Windchill>/prog_examples/adapter/windchill/customwebjects/src
|
ステップ 2: 新規 Webject の Windchill アダプタへの通知
新規 Webject 委任を Windchill アダプタが認識できるようにするには、wt.adapter.delegates.properties に登録する必要があります。
以下の行を追加します。
HELLOWORLD.WCTYPE|
java.lang.Object=ext.example.HelloWorldWebjectDelegate
このエントリは、新しい Webject 代理の名前 HELLOWORLD を指定します。また、この Webject が java.lang.Object というクラス (タイプ) のターゲットオブジェクトに対して有効であることを指定します。そして、実行する必要のある invoke() メソッドがどのクラスに含まれているかを示します。
この変更内容を認識するには、メソッドサーバーを再起動する必要があります。
ステップ 3: XML タスクの作成
次に、Hello-World Webject を記述する XML タスクドキュメントを作成します。タスクは、使用する Windchill サーバー用に設定したタスクディレクトリ内に作成する必要があります。以下に Hello-World.xml の例を示します。
|
タスクソースは以下のディレクトリにあります。
<Windchill>/prog_examples/adapter/windchill/customwebjects/tasks
|
<%@page language="java"%>
<%@taglib uri="http://www.ptc.com/infoengine/taglib/core" prefix="ie"%>
<!--com.infoengine.soap.rpc.def
This task simply invokes the Hello-World example adapter webject delegate
with generic input.
@return INFOENGINE_GROUP ${helloWorldResults}
-->
<ie:webject name="Create-Group" type="GRP">
<ie:param name="ELEMENT" data="a=b:b=c:c=d"/>
<ie:param name="ELEMENT" data="a=b1:b=c1:c=d1"/>
<ie:param name="ELEMENT" data="a=b2:b=c2:c=d2"/>
<ie:param name="ELEMENT" data="a=b3:b=c3:c=d3"/>
<ie:param name="GROUP_OUT" data="helloInput"/>
</ie:webject>
<ie:webject name="Hello-World" type="ACT">
<ie:param name="INSTANCE" data="$(@FORM[]supporting-adapter[*])"
delim="!" valueSeparator="!"
default="<%=com.infoengine.au.NamingService.getVMName(
)%>"/>
<ie:param name="GROUP_IN" data="helloInput" />
<ie:param name="GROUP_OUT" data="helloWorldResults" />
<ie:param name="HELLO_WHERE" data="out" />
<ie:param name="HELLO_WORLD" data="bob,steve,fred"
delim=","/>
<ie:param name="START" data="1" />
<ie:param name="STOP" data="2" />
</ie:webject>
ステップ 4: 新規 Webject 代理のテスト
Webject をテストするには、次の URL を実行します。
http://<yourIEServer>/<IEAlias>/Hello-World.xml
• <yourIEServer> は Info*Engine サーブレットを実行しているサーバーの名前です。
• <IEAlias> は Info*Engine タスクのために設定されたサーブレットエイリアスの名前です。
例:
http://host.company.com/Windchill/servlet/IE/tasks/ext/example/HelloWorld.xml
この URL から返される出力は、以下のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<wc:COLLECTION xmlns:wc="http://www.ptc.com/infoengine/1.0">
<Unknown-Class-Name
NAME="helloWorldResults"
TYPE="Unknown" STATUS="0">
<wc:INSTANCE>
<a>b1</a>
<b>c1</b>
<c>d1</c>
</wc:INSTANCE>
<wc:INSTANCE>
<a>b2</a>
<b>c2</b>
<c>d2</c>
</wc:INSTANCE>
</Unknown-Class-Name>
</wc:COLLECTION>
この例では、すべてのパラメータ値がハードコード化されます。
Info*Engine アノテーションの使用
ParameterDef アノテーションのデフォルト値は次のとおりです。
• type のデフォルトは String です (パラメータが文字列の場合、タイプの指定は不要です)。
• minValues のデフォルトは 0 です。
minValues により、パラメータが必要かどうかが決まります。0 より大きい値は、パラメータが必要であることを示しています。
• maxValues のデフォルトは 1 です。
maxValues により、Webject.objectParamValue の使用時に配列が返されるかどうかが決まります。
◦ 値が 0 以下の場合、パラメータは制限なしの複数値になります。この方法で定義されたパラメータの Webject.objectParamValue を呼び出すと、返されるオブジェクトの個数に制限がなく、0 以上のオブジェクトを含んで返される配列になります。
◦ 値が 1 の場合、パラメータが単一値であることを意味し (これがデフォルト)、配列は返されません。
◦ 値が 1 より大きい場合、パラメータが複数値であることを意味し、ユーザーは maxValues パラメータを超える指定ができません。合わせて minValues を指定すると、ユーザーがいくつ指定する必要があるかが決まります (0 はオプションであることを意味します)。
• デフォルトの defaultValue は "" です。これは実行時に Null と同じです。
|
単一値のパラメータが指定されないと、Null が返されます。そのため、ブール、整数などのデータタイプではデフォルトが重要です。デフォルト値が指定されていない場合、変数に結果を投入するだけではなく、Null になっていないかどうかを確認する必要があります。パラメータの論理的なデフォルト値は、常に推奨です。
|
以下に、ParameterDef アノテーションの使用時におけるその他の重要な点を挙げます。
• 複数値のパラメータがオプションであり、指定されていない場合は、空の配列が返されます。これは、単一値のパラメータの Null と矛盾しますが、複数値のパラメータで作業版数を実行する際に Null を明示的にチェックする必要性を避けるには好都合なので実行されます。
• 相互依存属性は、webject.validate で検証されます (これらの属性については後で説明します)。
• minValues および maxValues の値は webject.validate で検証されます。
たとえば、2 つの GROUP_IN パラメータが必要な場合、minValues="2" および maxValues="2" を設定します。グループを収集するときは、"Group [ ] grps = (Group [ ])webject.objectParamValue ( "GROUP_IN" )" のようにします。
その結果、grps 配列の長さは 2 となり、Webject で指定されたグループが含まれます。GROUP_IN パラメータの数が 2 つより多い、または少ない場合、例外が発生します。指定した GROUP_IN パラメータが VDB にないグループを参照した場合も、例外が発生します。
|
提供された基本クラスのいずれかを拡張し、親クラスによって収集されたパラメータをオーバーライドする場合、タイプ、多重度、パラメータを変更してはなりません。
アダプタ Webject が単一値の GROUP_IN パラメータを使用しているので、このパラメータを配列にすることはできません (前述のとおり)。共通のアダプタ基本クラスの 1 つを拡張する Webject でパラメータを必要とする場合、パラメータに一意の名前を付ける必要があります。
|
次に、追加の ParameterDef 属性を挙げます。
• interdependent - 相互依存パラメータ名の文字列。
• select - 互排他パラメータ名の文字列。
• exampleValue - ドキュメンテーション用。
ParameterDef の例
...
@ParameterDef(name="TYPE",interdependent={"WHERE"},select=
{"OBJECT_REF"},description="The business object type."),
@ParameterDef(name="WHERE,maxValues=-1,interdependent={"TYPE"},
select={"OBJECT_REF"},description="The where clause(s)."),
@ParameterDef(name="OBJECT_REF",maxValues=-1,
select={"TYPE","WHERE"},description="The ufid(s).",exampleValue="ufid")
...
上記の例では、以下の検証でエラーが発生します。
◦ TYPE または WHERE のいずれかを指定したが、両方ではない (パラメータがお互いに依存している)。
◦ OBJECT_REF が指定され、TYPE または WHERE のいずれかを指定した (TYPE パラメータと WHERE パラメータは OBJECT_REF に対して相互に排他的として定義されている)。
|
これらのアノテーションを使用する場合は、以下の階層で行います。
• サブクラスが、スーパークラス内の ParameterDefs をオーバーライドします。
• これらのアノテーションはインタフェース内でもサポートされるので、共有インタフェースからパラメータ定義を継承できます。
• 特に Windchill Webject および AbstractWebject に関連するので、パラメータをオーバーライドする際に注意が必要です。共通のアダプタ基本クラス (ObjectWebject、ActionWebject、または AbstractWebject) を拡張する際、パラメータのタイプや多重度を変更したり、defaultValue を除去したりしないでください。
変更や除去を行うと、基本クラスは自身のアノテーションに基づいてコード化され、クラスのアノテーションの拡張を認識しないので、ほぼ確実に Webject のバグが生じます。
|