第3章 ユーザーガイド
3.1. 構築

図3.1 org.drools.builder
3.1.1. コードによる構築
Knowledge Builder はソースデータを取得し、knowledge package に変換します。knowledge package には Knowledge Base が消費するルールおよびプロセス定義が含まれています。
注記
ResourceType オブジェクトクラスは構築されるリソースのタイプを示します。
ResourceFactory は、reader、クラスパス、URI、ファイルまたは ByteArray など含む複数のソースよりリソースをロードする機能を提供します。
重要

図3.2 KnowledgeBuilder
注記
Knowledge Builder は KnowledgeBuilderFactory によって作成されます。

図3.3 KnowledgeBuilderFactory
Knowledge Builder を作成します。
例3.1 新しい Knowledge Builder の作成
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
KnowledgeBuilderFactory を使用して設定を作成します。このような設定により Knowledge Builder の挙動を変更できるようになります。
注記
Knowledge Builder オブジェクトが解決できるようにするカスタム クラスローダー を提供するために、この設定の作成を行います。
例3.2 カスタムクラスローダーを使用した新しい Knowledge Builder の作成
KnowledgeBuilderConfiguration kbuilderConf =
KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(
null, classLoader );
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder(kbuilderConf);.drl ファイルが追加されます。
注記
Knowledge Builder は、JBoss Rules 4.0 Package Builder では不可能であった複数の名前空間の処理を行います。そのため、名前空間に関係なく、リソースの追加を継続することが可能です。
例3.3 DRL リソースの追加
kbuilder.add( ResourceFactory.newFileResource( "/project/myrules.drl" ),
ResourceType.DRL);重要
hasErrors() メソッドをチェックしてください。エラーがある時は、リソースを追加したり Knowledge Package を読み出したりしないでください (エラーがある場合、getKnowledgePackages() は空のリストを返します)。
例3.4 検証
if( kbuilder.hasErrors() )
{
System.out.println( kbuilder.getErrors() );
return;
}Knowledge Package の コレクション を取得します (「コレクション」と表現したのは、パッケージの名前空間ごとに 1 つの Knowledge Package があるからです)。これらの Knowledge Package は シリアライズ可能 で、頻繁にデプロイメントの単位として使用されます。
例3.5 Knowledge Package の取得
Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages();
例3.6 全要素の組み合わせ
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
if( kbuilder.hasErrors() ) {
System.out.println( kbuilder.getErrors() );
return;
}
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newFileResource( "/project/myrules1.drl" ),
ResourceType.DRL);
kbuilder.add( ResourceFactory.newFileResource( "/project/myrules2.drl" ),
ResourceType.DRL);
if( kbuilder.hasErrors() )
{
System.out.println( kbuilder.getErrors() );
return;
}
Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages();3.1.2. 設定および Change-Set XML を用いた構築
警告
例3.7 Change-Set XML のスキーマ (非「規範的」)
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://drools.org/drools-5.0/change-set"
targetNamespace="http://drools.org/drools-5.0/change-set">
<xs:element name="change-set" type="ChangeSet"/>
<xs:complexType name="ChangeSet">
<xs:choice maxOccurs="unbounded">
<xs:element name="add" type="Operation"/>
<xs:element name="remove" type="Operation"/>
<xs:element name="modify" type="Operation"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="Operation">
<xs:sequence>
<xs:element name="resource" type="Resource"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Resource">
<xs:sequence>
<!-- To be used with <resource type="DTABLE"...>> -->
<xs:element name="decisiontable-conf" type="DecTabConf"
minOccurs="0"/>
</xs:sequence>
<!-- java.net.URL, plus "classpath" protocol -->
<xs:attribute name="source" type="xs:string"/>
<xs:attribute name="type" type="ResourceType"/>
<xs:attribute name="basicAuthentication" type="xs:string"/>
<xs:attribute name="username" type="xs:string"/>
<xs:attribute name="password" type="xs:string"/>
</xs:complexType>
<xs:complexType name="DecTabConf">
<xs:attribute name="input-type" type="DecTabInpType"/>
<xs:attribute name="worksheet-name" type="xs:string"
use="optional"/>
</xs:complexType>
<!-- according to org.drools.builder.ResourceType -->
<xs:simpleType name="ResourceType">
<xs:restriction base="xs:string">
<xs:enumeration value="DRL"/>
<xs:enumeration value="XDRL"/>
<xs:enumeration value="DSL"/>
<xs:enumeration value="DSLR"/>
<xs:enumeration value="DRF"/>
<xs:enumeration value="DTABLE"/>
<xs:enumeration value="PKG"/>
<xs:enumeration value="BRL"/>
<xs:enumeration value="CHANGE_SET"/>
</xs:restriction>
</xs:simpleType>
<!-- according to org.drools.builder.DecisionTableInputType -->
<xs:simpleType name="DecTabInpType">
<xs:restriction base="xs:string">
<xs:enumeration value="XLS"/>
<xs:enumeration value="CSV"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
注記
<xs:attribute name="basicAuthentication" type="xs:string"/>
<xs:attribute name="username" type="xs:string"/>
<xs:attribute name="password" type="xs:string"/>
重要
.drl ファイルをロードします。
例3.8 単純な Change-Set XML
<change-set xmlns='http://drools.org/drools-5.0/change-set'
xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd' >
<add>
<resource source='file:/project/myrules.drl' type='DRL' />
</add>
</change-set>
file や http など java.net.URL によって提供されるすべてのプロトコルをサポートし、classpath の追加バージョンもサポートします。
重要
ClassPath resource loader を使用して、リソースの特定に使用される class loader を指定します (XML では不可能です)。デフォルトでは、Knowledge Builder によって使用される class loader が使用されます (Change-Set XML が ClassPath リソースによってロードされる場合を除きます。この場合、リソースに対して指定された class loader が使用されます)。
例3.9 Change-Set XML のロード
kbuilder.add(ResourceFactory.newUrlResource(url),ResourceType.CHANGE_SET);
例3.10 リソース設定を用いた Change-Set XML
<change-set xmlns='http://drools.org/drools-5.0/change-set'
xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd' >
<add>
<resource source='http:org/domain/myrules.drl' type='DRL' />
<resource source='classpath:data/IntegrationExampleTest.xls'
type="DTABLE">
<decisiontable-conf input-type="XLS" worksheet-name="Tables_2" />
</resource>
</add>
</change-set>Knowledge Base を再構築するため、Change-Set は Knowledge Agent を使用する時に便利です (これらの機能の詳細は Knowledge Agent の項の「デプロイメント」に記載されています)。
Knowledge Agent を使用する場合、リソースへの変更を継続的にスキャンします。また、キャッシュされた Knowledge Base も再構築します。
注記
Knowledge Agent と併用することも可能です。詳細は 「KnowledgeAgent」 を参照してください。
例3.11 ディレクトリの内容を追加するための Change-Set XML コード
<change-set xmlns='http://drools.org/drools-5.0/change-set'
xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd' >
<add>
<resource source='file:/projects/myproject/myrules' type='DRL' />
</add>
</change-set>3.2. デプロイメント
3.2.1. KnowledgePackage とナレッジ定義
KnowledgePackage は KnowledgeBuilder によって作成されます。KnowledgePackage は自己充足的で、シリアライズ可能です。現在の基本的なデプロイメントユニットを形成します。

図3.4 KnowledgePackage
重要
KnowledgePackage は Knowledge Base に追加されますが、KnowledgePackage インスタンスは追加されると再使用できないことに注意してください。別の knowledge base に追加するには、最初に シリアライズ を行い、「クローン」された結果を使用します。 JBoss Rules の今後のバージョンでは、この制限がなくなる予定です。
3.2.2. ナレッジベース

図3.5 ナレッジベース
knowledge base は、アプリケーションすべての ナレッジ定義 が格納されるレポジトリです。これには、ルール、プロセス、関数およびタイプモデルが含まれます。knowledge base 自体には「インスタンス」データ (ファクト) は含まれません。この代わりに、セッションは Knowledge Base より作成されます。facts は Knowledge Base へ挿入され、process instances は Knowledge Base より開始します。
重要
knowledge base の作成は比較的リソースを多く使用するプロセスですが、セッションの作成はそうではありません。よって、セッションを繰り返し作成できるようにするため、Red Hat は可能な限り knowledge bases をキャッシュすることを推奨します。
knowledge bases オブジェクトも シリアライズ可能 であるため、構築して保存する方がよいでしょう。こうすることで、knowledge packages ではなくデプロイメントの単位として取り扱うことが可能です。
knowledge base を作成する方法の 1 つが KnowledgeBaseFactory クラスを使用する方法です。

図3.6 KnowledgeBaseFactory
例3.12 新しいナレッジベースの作成
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
Knowledge Builder と共にカスタマイズされた class-loader を使用してデフォルトの loader にない types を解決したい場合、これを Knowledge Base に設定します (このテクニックは Knowledge Builder に適用されるものと同じです)。
例3.13 カスタム Class-Loader を用いた新しいナレッジベースの作成
KnowledgeBaseConfiguration kbaseConf =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration( null, cl );
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase( kbaseConf );3.2.3. インプロセス構築およびデプロイメント
knowledge base に追加されます。
重要
drools-${module}-${version}.jar ファイルが必ずクラスパス上にあるようにしてください。
例3.14 Knowledge Packages の Knowledge Base への追加
Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages(); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( kpkgs );
注記
addKnowledgePackages(kpkgs) メソッドは繰り返し呼び出せることを理解してください。これはナレッジを追加するために行います。
3.2.4. 別プロセスとしての構築およびデプロイメント
Knowledge Base と KnowledgePackage は両方ともデプロイメントの単位であるため、シリアライズすることが可能です。そのため、drools-compiler.jar に必要な構築を実行するため 1 つのマシンを割り当て、すべてをデプロイおよび実行するために他のマシンを確保することができます。2 つ目のマシンは drools-core.jar のみを必要とします。
例3.15 KnowledgePackage を出力ストリームへ書き込む
ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream( fileName ) ); out.writeObject( kpkgs ); out.close();
例3.16 入力ストリームから KnowledgePackage を読み取る
ObjectInputStream in = new ObjectInputStream( new FileInputStream( fileName ) );
// The input stream might contain an individual
// package or a collection.
@SuppressWarnings( "unchecked" )
Collection<KnowledgePackage> kpkgs =
()in.readObject( Collection<KnowledgePackage> );
in.close();
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages( kpkgs );
knowledge base 自体もシリアライズ可能であるため、ナレッジパッケージではなく構築と保存を行うことが推奨されます。
注記
knowledge packages を URL へコンパイルおよびパブリッシュした後、このアドレスリソースタイプを使用してこれらをロードできます。
3.2.5. ステートフルナレッジセッションとナレッジベースの変更
Knowledge Base によって作成され、返されます。また、任意で参照を保持することも可能です。Knowledge Base が変更されると、変更はセッションのデータに適用されます。これは弱い任意の参照で、ブール値フラグによって制御されます。
3.2.6. KnowledgeAgent
KnowledgeAgent は、リソースの自動ロード、キャッシュ、および再ロードを提供するクラスで、プロパティーファイルより設定されます。使用するリソースが変更されると、KnowledgeAgent は Knowledge Base を更新または再構築することができます。factory の設定は使用されるストラテジーを決定します (通常はプルベースで、標準のポーリングを使用します)。
注記
KnowledgeAgent は、デフォルトのポーリング間隔 (60 秒) で追加されたリソースをすべて継続してスキャンします。最後の変更の日付が更新されると、キャッシュされた Knowledge Base は新しいリソースを使用して自動的に再構築されます。

図3.7 KnowledgeAgent
KnowledgeBuilderFactory オブジェクトは Knowledge Builder を作成するために使用されます。ログファイルが必要とするため、エージェントは名前を指定する必要があります (ログエントリを正しいエージェントへ関連付けできるようにするためです)。
例3.17 KnowledgeAgent の作成
KnowledgeAgent kagent =
KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent" );

図3.8 KnowledgeAgentFactory
knowledge base を構築するエージェントを構築します。
注記
注記
KnowledgeAgent は、change set から追加されたリソースを 60 秒ごと (デフォルトの間隔) にポーリングして、更新されたか確認します。変更が検出されると、新しい Knowledge Base を構築します。また、ディレクトリがリソースとして指定された場合は、その内容がスキャンされます。
例3.18 KnowledgePackage を出力ストリームへ書き込む
KnowledgeAgent kagent =
KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent" );
kagent.applyChangeSet( ResourceFactory.newUrlResource( url ) );
KnowledgeBase kbase = kagent.getKnowledgeBase();
ResourceFactory を用いてアクティベートします。
例3.19 スキャンおよび通知サービスの開始
ResourceFactory.getResourceChangeNotifierService().start(); ResourceFactory.getResourceChangeScannerService().start();
ResourceChangeScannerService クラスより、デフォルトのリソーススキャン期間を変更します (更新された ResourceChangeScannerConfiguration オブジェクトはサービスの configure() メソッドに渡されるため、サービスは要求に応じて再設定できるようになります)。
例3.20 スキャン間隔の変更
ResourceChangeScannerConfiguration sconf =
ResourceFactory.getResourceChangeScannerService().
newResourceChangeScannerConfiguration();
// Set the disk scanning interval to 30s, default is 60s.
sconf.setProperty( "drools.resource.scanner.interval", "30" );
ResourceFactory.getResourceChangeScannerService().configure( sconf );
KnowledgeAgents は、空の Knowledge Bases と値が入力されたKnowledge Bases の両方を処理できます。値が入力された Knowledge Bases が提供された場合、KnowledgeAgent が内部から イテレーター を実行し、見つかった各リソースをサブスクライブします。
警告
KnowledgeBuilder がディレクトリのリソースをすべて構築するようにすることは可能ですが、この情報は失われます。つまり、これらのディレクトリは連続してスキャンされません。applyChangeSet(Resource) メソッドによって指定されたディレクトリのみが監視されます。
注記
Knowledge Base を土台として使用する利点の 1 つは、KnowledgeBaseConfiguration クラスで Knowledge Base を提供できることです。リソースの変更が検出され、新しい Knowledge Base がインスタンス化されると、以前の Knowledge Base オブジェクトに属する KnowledgeBaseConfiguration クラスが使用されます。
例3.21 既存のナレッジベースの使用
KnowledgeBaseConfiguration kbaseConf =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration( null, cl );
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase( kbaseConf );
// Populate kbase with resources here.
KnowledgeAgent kagent =
KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent", kbase );
KnowledgeBase kbase = kagent.getKnowledgeBase();
Knowledge Base が構築されるまで getKnowledgeBase() メソッドは同じ Knowledge Base インスタンスを返します。これは、以前の Knowledge Base へ提供された KnowledgeBaseConfiguration を用いて行われます。
例3.22 ディレクトリの内容を追加する Change-Set XML
<change-set xmlns='http://drools.org/drools-5.0/change-set'
xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd' >
<add>
<resource source='file:/projects/myproject/myrules' type='PKG' />
</add>
</change-set>
注記
drools-compiler 依存関係は、PKG という名前のリソースタイプには必要ありません。KnowledgeAgent は drools-core のみを用いてこのようなリソースタイプに対応できます。
KnowledgeAgentConfiguration を使用して KnowledgeAgent のデフォルトの動作を変更します。これは、変更に対するディレクトリの連続スキャンを抑制しながらディレクトリよりリソースをロードするために行います。
例3.23 スキャンの挙動変更
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
KnowledgeAgentConfiguration kaconf =
KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
// Do not scan directories, just files.
kaconf.setProperty( "drools.agent.scanDirectories", "false" );
KnowledgeAgent kagent =
KnowledgeAgentFactory.newKnowledgeAgent( "test agent", kaconf );
Knowledge Packages を構築およびパブリッシュする方法と、Change-Set XML が URL とパッケージの両方を処理する方法を見てきました。これらの方法は、Knowledge Agent の重要なデプロイメントのシナリオを形成します。
3.3. 実行
3.3.1. ナレッジベース
Knowledge Base 自体にはインスタンスデータ (ファクト と呼ばれます) は含まれません。ファクトが挿入でき、プロセスインスタンスが起動できる KnowledgeBase よりセッションが作成されます。
注記
Knowledge Base の作成はリソースを大量に消費するプロセスですが、セッションの作成はリソースを大量に消費しません。繰り返しセッションを作成できるようにするため、可能な限り Knowledge Bases をキャッシュするようにしてください。
例3.24 新しいナレッジベースの作成
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
3.3.2. StatefulKnowledgeSession
StatefulKnowledgeSession はランタイムデータを格納し、実行します。StatefulKnowledgeSession は KnowledgeBase より作成されます。

図3.9 StatefulKnowledgeSession
例3.25 KnowledgeBase より StatefulKnowledgeSession を作成
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
3.3.3. KnowledgeRuntime
3.3.3.1. WorkingMemoryEntryPoint
WorkingMemoryEntryPoint は、ファクトを挿入、更新、および読み出しするメソッドを提供します。
注記
working memory に複数のパーティションが存在し、ファクトが挿入されるパーティションを選択できることに関連しています。しかし、このユースケースはイベント処理を対象とし、ほとんどのルールベースのアプリケーションはデフォルトのエントリーポイントのみを使用します。
KnowledgeRuntime インターフェースは engine と主な対話を行い、ルールの結果とプロセスのアクションで使用可能です。メソッドとインターフェースに関連するルールに焦点を置きますが、KnowledgeRuntime は WorkingMemory と ProcessRuntime の両方よりメソッドを継承します。これは、プロセスとルールに対応する統合 API を提供します。ルールを用いて作業する時、WorkingMemoryEntryPoint、WorkingMemory、および KnowledgeRuntime の 3 つのインターフェースが KnowledgeRuntime を形成します。

図3.10 WorkingMemoryEntryPoint
3.3.3.1.1. 挿入 (insert)
WorkingMemory にファクトについて通知する行為です (ksession.insert(yourObject) など)。挿入が行われると、システムはルールに対する一致があるか各ファクトを調べます。ルール実行の有無に関する決定はすべて挿入時に行われます。ただし、fireAllRules() が呼び出されるまでルールは実行されません。必ずすべてのファクトが挿入された後に行います。
注記
fireAllRules() が呼び出された時に条件評価が行われるという誤った考えを持ったユーザーが過去に存在しました。
注記
FactHandle は working memory 内で挿入されたオブジェクトを示すために使用されるトークンです。 オブジェクトが変更または取り消された時に、working memory との対話にも使用されます。
Cheese stilton = new Cheese("stilton");
FactHandle stiltonHandle = ksession.insert( stilton );working memory は、equality と identity の 2 つのアサーションモードのいずれかで操作します (デフォルトは identity です)。
Identityが使用される場合、working memoryはIdentityHashMapを使用してアサートされたオブジェクトをすべて格納します。インスタンスが新たにアサートされると、常に新しいFactHandleが返されます。同じインスタンスを繰り返し挿入すると、元のファクトハンドルが返されます。Equalityが使用される場合、working memoryはHashMapを使用してアサートされたオブジェクトをすべて格納します。同等のオブジェクトがアサートされていない場合、インスタンスが新たにアサートされると、新しいFactHandleのみが返されます。
3.3.3.1.2. 取り消し
working memory よりファクトを削除することを意味します。ファクトの追跡やルールの一致は行われないようになります。さらに、そのファクトに依存するアクティベートされたルールは、キャンセルされます。取り消しは、アサート時に返された FactHandle を使用して実行されます。
注記
not および exist キーワードを使用)。このような場合にファクトを取り消すと、ルールがアクティベートされる原因となることがあります。
Cheese stilton = new Cheese("stilton");
FactHandle stiltonHandle = ksession.insert( stilton );
ksession.retract( stiltonHandle );3.3.3.1.3. 更新
rule engine に通知し、変更されたファクトを再処理できるようにする必要があります。ファクトが更新済みであると見なされる場合、working memory より自動的に取り消され、再度挿入されます。
working memory 自体に通知できない場合、update メソッドを使用して通知します。update メソッドは常に変更されたオブジェクトをセカンダリパラメーターとして取ります。これにより、新しいインスタンスを 不変オブジェクト に対して指定できます。
注記
update メソッドは、シャドウプロキシ が有効になったオブジェクトのみに使用できます。
重要
update メソッドは Java コードと併用する場合のみ使用できます。オブジェクトの setter メソッドへの呼び出しを提供するため、ルール内で modify キーワードを使用します。
Cheese stilton = new Cheese("stilton");
FactHandle stiltonHandle = workingMemory.insert( stilton );
...
stilton.setPrice( 100 );
workingMemory.update( stiltonHandle, stilton );3.3.3.2. ワーキングメモリー
working memory は agenda へのアクセスを提供します。また、クエリの実行を許可し、名前付きの entry points へのアクセスを許可します。

図3.11 ワーキングメモリー
3.3.3.2.1. クエリ
Knowlege Base にクエリを定義します。Knowlege Base よりクエリを呼び出して一致する結果を返します。結果コレクション上で繰り替えされる間、get(String identifier) メソッドを使用してクエリのバインド識別子へアクセスできます。getFactHandle(String identifier) を使用すると、その識別子の FactHandle を読み出すことができます。

図3.12 クエリ結果

図3.13 QueryResultsRow
例3.26 簡単なクエリの例
QueryResults results =
ksession.getQueryResults( "my query", new Object[] { "string" } );
for ( QueryResultsRow row : results ) {
System.out.println( row.get( "varName" ) );
}3.3.3.3. ライブクエリ
例3.27 ViewChangedEventListener の実装
final List updated = new ArrayList();
final List removed = new ArrayList();
final List added = new ArrayList();
ViewChangedEventListener listener = new ViewChangedEventListener() {
public void rowUpdated(Row row) {
updated.add( row.get( "$price" ) );
}
public void rowRemoved(Row row) {
removed.add( row.get( "$price" ) );
}
public void rowAdded(Row row) {
added.add( row.get( "$price" ) );
}
};
// Open the LiveQuery
LiveQuery query = ksession.openLiveQuery( "cheeses",
new Object[] { "cheddar", "stilton" },
listener );
...
...
query.dispose() // make sure you call dispose when you want the query to close3.3.3.4. KnowledgeRuntime
KnowledgeRuntime は、ルールとプロセスの両方へ適用可能なその他のメソッドを提供します。グローバルを設定したり、ExitPoints を登録するメソッドがこの一例となります。

図3.14 KnowledgeRuntime
3.3.3.4.1. グローバル
rule engine へ渡すことができる名前付きオブジェクトです。挿入する必要はありません。統計情報やルールの右側で使用されるサービスに対して最も頻繁に使用されます。また、rule engine よりオブジェクトを返す手段としても使用されます。
- 不変であることを確認します。
- セッションに設定する前に
rulesファイルで宣言します。global java.util.List list
- これで、
Knowlege Baseがグローバル識別子とそのタイプを認識するようになったため、任意セッションのksession.setGlobalを呼び出します。警告
最初にグローバルタイプと識別子を宣言しないと、例外がスローされます。 - セッションにグローバルを設定するには、
ksession.setGlobal(identifier, value)を使用します。List list = new ArrayList(); ksession.setGlobal("list", list);警告
設定される前にルールがグローバルを評価すると、NullPointerException例外がスローされます。
3.3.3.5. StatefulRuleSession
NullPointerException は StatefulKnowledgeSession によって継承されます。これは、engine 外部に適用可能なルール関連のメソッドを提供します。

図3.15 StatefulRuleSession
3.3.3.5.1. アジェンダ フィルター

図3.16 AgendaFilters
filter インターフェースの実装です。アジェンダフィルターを使用して実行権利の有効化を許可または拒否します (フィルターできるかは実装に完全依存します)。
注記
fireAllRules() を呼び出す時に指定します。次の例では、 Test という文字列で終わるルールのみ実行が許可されます。他のルールはフィルターによって除外されます。
ksession.fireAllRules( new RuleNameEndsWithAgendaFilter( "Test" ) );
3.3.4. アジェンダ
working memory でアクションが実行される時、ルールが完全一致すると実行可能になります。単一の working memory アクションによって複数のルールを実行可能にできます。ルールが完全一致すると、アクティベーションが作成されます。これはルールと、一致するファクトの両方を参照し、Agenda 上に置かれます。次に Agenda は、競合解決ストラテジを介してアクティベーションの順序を決定します。
engine は 2 つの段階を繰り返します。
- 最初の段階は ワーキングメモリーアクション段階 と呼ばれます。ほとんどの作業はこの段階で行われ、 結果 (右側) または主要な Java アプリケーションプロセスのいずれかになります。結果が終了したり、主要の Java アプリケーションが
fireAllRules()を呼び出すと、engineがアジェンダの第 2 段階へ切り替えられます。 - 第 2 段階は アジェンダ評価段階 と呼ばれます。この段階でシステムは実行するルールを検索します。何も検出されないと終了します。検出されたルールがある場合はそのルールを実行し、その後ワーキングメモリーアクション段階へ切り替えます。

図3.17 2段階の実行
- プロセスは
agendaが消去されるまで繰り替えされ、消去された時点で時間制御が呼び出しアプリケーションへ返されます。注記
ワーキングメモリーアクションの実行中、ルールは実行されません。
図3.18 アジェンダ
3.3.4.1. 競合の解決
agenda に複数のルールがある場合、競合解決ストラテジが必要となります。ルールの実行はワーキングメモリーに影響を与えることがあるため、rule engine はルールが実行される順序を認識する必要があります (たとえば、ruleA を実行すると ruleB がアジェンダより削除される原因となることがあります)。
- Salience
- LIFO (後入れ先出し)
working memory の action counter 値を基に優先度を決定します。同じアクションが同じ値を受け取る間に各ルールが作成されます (実行のセットが同じ優先度値を持つ場合、実行順序は任意になります)。
重要
注記
3.3.4.2. AgendaGroup

図3.19 AgendaGroup
agenda 上のアクティベーションを分割します。常に 1 つのグループのみが「フォーカス」を持つことができ、そのグループに属するアクティベーションのみを有効にできます。
注記
Agenda groups は最も一般的に使用されます。
agenda group が一致するとフォーカスされます)。
setFocus() が呼び出されるたびに、agenda group が スタック にプッシュされます。フォーカスグループが空である場合、スタックから削除され、次のフォーカスグループ (この時点で一番上のグループ) を評価することが許可されます。
注記
agenda group はスタックの複数の場所に表示できます。
ksession.getAgenda().getAgendaGroup( "Group A" ).setFocus();
agenda group グループは MAIN と呼ばれます。これがスタックの最初のグループで、最初にフォーカスを持ちます。agenda group のないルールは自動的にこのグループに置かれます。
3.3.4.3. アクティベーショングループ

図3.20 ActivationGroup
activation group は activation-group ルール属性によってバインドされるルールのセットです。このグループでは 1 つのルールのみが実行できます。そのルールが実行した後、他のルールはすべてキャンセルされます。
注記
clear() メソッドを呼び出し、アクティベーションが実行する前にすべてのアクティベーションをキャンセルします。
ksession.getAgenda().getActivationGroup( "Group B" ).clear();
3.3.5. イベントモデル
event package は rule engine イベントの1つに通知します。これを使用して、アプリケーションの主な部分やルールから、ロギングおよび監査のアクティビティーを切り離します。
KnowledgeRuntimeEventManager インターフェースは KnowledgeRuntime クラスによって実装されます。このクラスは、WorkingMemoryEventManager と ProcessEventManager の 2 つのインターフェースを提供します。
注記
WorkingMemoryEventManager のみ取り上げます。

図3.21 KnowledgeRuntimeEventManager
WorkingMemoryEventManager を使用してリスナーを追加および削除します。リスナーを追加すると、working memory および agenda に影響するイベントを「リッスン」できます。

図3.22 WorkingMemoryEventManager
agenda listener を宣言し、セッションにアタッチする方法を表しています。アクティベーションが実行された後に、アクティベーションを出力します。
例3.28 AgendaEventListener の追加
ksession.addEventListener( new DefaultAgendaEventListener() {
public void afterActivationFired(AfterActivationFiredEvent event) {
super.afterActivationFired( event );
System.out.println( event );
}
});DebugWorkingMemoryEventListener および DebugAgendaEventListener と呼ばれる 2 つのクラスも提供します。すべての working memory イベントを出力するには、これらリスナーの 1 つを追加します。
例3.29 新しい KnowledgeBuilder の作成
ksession.addEventListener( new DebugWorkingMemoryEventListener() );
KnowledgeRuntime を読み出すには、KnowledgeRuntimeEvent インターフェースを使用します。

図3.23 KnowledgeRuntimeEvent
| ActivationCreatedEvent | ActivationCancelledEvent |
| BeforeActivationFiredEvent | AfterActivationFiredEvent |
| AgendaGroupPushedEvent | AgendaGroupPoppedEvent |
| ObjectInsertEvent | ObjectRetractedEvent |
| ObjectUpdatedEvent | ProcessCompletedEvent |
| ProcessNodeLeftEvent | ProcessNodeTriggeredEvent |
| ProcessStartEvent |
3.3.6. KnowledgeRuntimeLogger
KnowledgeRuntimeLogger は JBoss Rules の event system を使用して監査ログを作成します。JBoss Rules IDE の Audit Viewer などのツールを使用してこのログを調査します。

図3.24 KnowledgeRuntimeLoggerFactory
例3.30 FileLogger
KnowledgeRuntimeLogger logger =
KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "logdir/mylogfile");
...
logger.close();newFileLogger() メソッドを使用して、自動的にファイル拡張子 .log をファイルへ追加します。
3.3.7. StatelessKnowledgeSession
StatelessKnowledgeSession は StatefulKnowledgeSession をラッピングし、決定サービスタイプのシナリオに関連して使用されます。この存在により、dispose() の呼び出しが軽減されます。
fireAllRules() メソッドを呼び出したりすることはできません。 execute() メソッドは内部で StatefullKnowledgeSession をインスタンス化し、ユーザーデータをすべて追加してユーザーコマンドを実行します。その後、fireAllRules() および dispose() メソッドを呼び出します。
BatchExecution コマンドよりこのクラスを使用します (CommandExecutor インターフェースによってサポートされます)。しかし、2 つの 簡便性 (convenience) メソッド も提供されています。これらのメソッドは、簡単なオブジェクト挿入が必要な場合のみ使用します (CommandExecutor および BatchExecution は独自の項で詳細に説明されています)。

図3.25 StatelessKnowledgeSession
Convenience API を使用して stateless session を実行することを表しています。コレクションを繰り返し処理し、各要素を順に挿入します。
例3.31 コレクションを用いた簡単な StatelessKnowledgeSession の実行
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newFileResource( fileName ), ResourceType.DRL );
if (kbuilder.hasErrors() ) {
System.out.println( kbuilder.getErrors() );
} else {
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
ksession.execute( collection );
}例3.32 InsertElements コマンドを用いた簡単な StatelessKnowledgeSession の実行
ksession.execute( CommandFactory.newInsertElements( collection ) );
CommandFactory.newInsert(collection) を使用します。
CommandFactory にはサポートされるコマンドの詳細が含まれています。これらのコマンドのいずれかをマーシャリングするには XStream および BatchExecutionHelper を使用します。 また、BatchExecutionHelper を使用して、使用される XML 形式の詳細について学びます。JBoss Rules Pipeline を使用して、自動的に BatchExecution および ExecutionResults をマーシャリングします。
StatelessKnowledgeSession はさまざまなやり方でグローバルをスコープ指定できるようにします。最初はコマンドではない方法です。コマンドは特定の実行呼び出しへスコープ指定されます (グローバルは 3 つの方法で解決されます)。
StatelessKnowledgeSessionのgetGlobals()メソッドはGlobalsインスタンスを返します。名前の通り、このメソッドはセッションのグローバルへのアクセスを提供します。セッションのグローバルは すべての 実行呼び出しによって共有されます。警告
実行呼び出しは異なるスレッドで同時に実行できるため、可変グローバル を扱う場合は注意が必要です。例3.33 セッションスコープグローバル
StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession(); // sets a global hibernate session, that can be used // for DB interactions in the rules. ksession.setGlobal( "hbnSession", hibernateSession ); // Execute while being able to resolve the "hbnSession" identifier. ksession.execute( collection );
- 委譲を使用してグローバル解決を実行する方法もあります。グローバルに値を割り当てると (
setGlobal(String, Object)を使用)、値は内部コレクションに格納されます。これは、識別子を値へマッピングすることが目的です。これらの識別子は提供される委譲よりも優先されます。識別子が見つからない場合のみ委譲グローバル (存在する場合) が使用されます。 - グローバルを解決する 3 つ目の方法は、 実行スコープグローバル を使用することです。この場合、グローバルを設定するコマンドは
CommandExecutorへ渡されます。
CommandExecutor インターフェースは out パラメーターを用いてデータをエクスポートする機能も提供します。挿入されたファクト、グローバル、およびクエリの結果はすべて返すことが可能です。
例3.34 out 識別子
// Set up a list of commands List cmds = new ArrayList(); cmds.add( CommandFactory.newSetGlobal( "list1", new ArrayList(), true ) ); cmds.add( CommandFactory.newInsert( new Person( "jon", 102 ), "person" ) ); cmds.add( CommandFactory.newQuery( "Get People" "getPeople" ); // Execute the list ExecutionResults results = ksession.execute( CommandFactory.newBatchExecution( cmds ) ); // Retrieve the ArrayList results.getValue( "list1" ); // Retrieve the inserted Person fact results.getValue( "person" ); // Retrieve the query as a QueryResults instance. results.getValue( "Get People" );
3.3.7.1. シーケンシャルモード
engine は簡素化された方法で稼働できます。以下の手順に従ってください。
- ルールセットの salience と position によりルールの順番を決定します (
rule terminalノードの sequence 属性を設定します)。 - 可能なルールアクティベーションごとに 1 つの要素を持つアレイを作成します。要素のポジションが実行順序を表します。
- right-input オブジェクトメモリー 以外の ノードメモリー をすべてオフにします。
Left Input Adapter Node伝播の接続を切断し、コマンドオブジェクトがオブジェクトとノードを参照できるようにします。後で実行するために、このコマンドオブジェクトはworking memoryのリストに追加されます。- すべてのオブジェクトをアサートします。アサートが実行され、right-input ノードメモリーにデータが投入されると、コマンドリストを確認し、各項目を順番に実行します。
- ルールに対して決定されたシーケンス番号に従って、結果となるすべてのアクティベーションをアレイに格納します。繰り返し処理の範囲を縮小するため、最初と最後に投入された要素を記録します。
- アクティベーションのアレイを繰り返し処理し、投入された要素を順番に実行します。
- 許可される最大ルール実行数が存在する場合、アレイのルールをすべて実行するため、ネットワーク評価を早期に終了します。
注記
LeftInputAdapterNode によって実行されないようになりました。代わりに、コマンドオブジェクトが作成され、working memory のリストに追加されるようになりました。このオブジェクトには、LeftInputAdapterNode と伝播されたオブジェクト両方への参照が含まれます。これにより、 挿入時に left-input 伝播が発生しないようにするため、left-input で結合を実行しようとする right-input 伝播はありません (よって、left-input メモリーが不必要になります)。
LeftInputAdapterNode コマンドオブジェクトを順に呼び出し、LeftInputAdapterNode コマンドオブジェクトのリストを繰り返し処理します。これらのコマンドオブジェクトはネットワークへ渡され、right-input オブジェクトと結合しようとしますが、right-input メモリーへアサートまたは伝播されるオブジェクトはこれ以上ないため、left-input には記録されません。
注記
agenda はなくなりました。代わりに、ルールの数に対する簡単なアレイが存在します。RuleTerminalNode のシーケンス番号はアクティベーションを格納するアレイ内の要素を表します。
重要
RuleTerminalNode にシーケンス番号が割り当てられ、ネットワークが構築されます。この番号は、salience 番号とネットワークに追加された順序に基づいています。
重要
RuleBaseConfiguration.setSequential(true) を呼び出すか、ルールベース設定の drools.sequential プロパティーを true に設定します。
注記
SequentialAgenda.DYNAMIC を用いて setSequentialAgenda を呼び出し、シーケンシャルモードが動的アジェンダへフォールバックするようにします。また、drools.sequential.agenda プロパティーを sequential または dynamic に設定することもできます。
3.3.8. コマンドと CommandExecutor
working memory を使用します。ステートレスセッションは、提供されたデータセットを用いて working memory を一度だけ実行します。結果がいくつか返される可能性があり、対話が繰り返し行われないようにするためセッションは最後に破棄されます。ステートレスセッションは、任意の結果を返す関数として rule engine を処理する方法であると考えてください。

図3.26 CommandExecutor

図3.27 ExecutionResults
CommandFactory はコマンドをステートフルおよびステートレスセッションで実行できるようにします (ステートレスナレッジセッションは破棄される前に fireAllRules() を最後に実行することが唯一の違いとなります)。現在サポートされているコマンドは次の通りです。
| FireAllRules | GetGlobal |
| SetGlobal | InsertObject |
| InsertElements | クエリ |
| StartProcess | BatchExecution |
InsertObject は任意の out 識別子を用いて単一オブジェクトを挿入します。InsertElements は繰り返し処理が可能なオブジェクトを確認し、各要素を挿入します。その結果、ステートレスナレッジセッションへオブジェクトを挿入するだけでなく、プロセスを開始したりクエリを実行したりして任意の順番でこれを実行できるようになります。
例3.35 insert コマンド
StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession(); ExecutionResults bresults = ksession.execute( CommandFactory.newInsert( new Cheese( "stilton" ), "stilton_id" ) ); Stilton stilton = bresults.getValue( "stilton_id" );
ExecutionResults インスタンスを返します。これにより、上記の stilton_id などの out 識別子が指定されていると、すべてのコマンドの結果にアクセスできます。
例3.36 InsertElements コマンド
StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
Command cmd = CommandFactory.newInsertElements(
Arrays.asList(new Object[] {
new Cheese("stilton"), new Cheese("brie"), new Cheese("cheddar")}
));
ExecutionResults bresults = ksession.execute( cmd );重要
BatchExecution は命令リストを取る複合コマンドで、これらの命令を順番に繰り返し処理し、実行します。そのため、オブジェクトをいくつか挿入してプロセスを開始し、fireAllRules を呼び出して単一の execute(...) 呼び出しでクエリを実行できるため、大変強力なコマンドになります。
fireAllRules() メソッドを自動的に実行しますが、FireAllRules コマンドも許可されます。このコマンドを使用すると、最後に自動実行が無効になります。これは手動のオーバーライドです。
ExecutionResults インスタンスにその結果を追加します。次の例はこの仕組みを表しています。
例3.37 BatchExecution コマンド
StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession(); List cmds = new ArrayList(); cmds.add( CommandFactory.newInsertObject( new Cheese( "stilton", 1), "stilton") ); cmds.add( CommandFactory.newStartProcess( "process cheeses" ) ); cmds.add( CommandFactory.newQuery( "cheeses" ) ); ExecutionResults bresults = ksession.execute( CommandFactory.newBatchExecution( cmds ) ); Cheese stilton = ( Cheese ) bresults.getValue( "stilton" ); QueryResults qresults = ( QueryResults ) bresults.getValue( "cheeses" );
ExecutionResults にデータを投入します。query コマンドはデフォルトではクエリ名と同じ識別子を使用しますが、異なる識別子へマッピングすることも可能です。
XStream マーシャラーを JBoss Rules Pipeline と共に使用すると XML スクリプトを提供できるため、サービスに最適です。以下は、BatchExecution と ExecutionResults 向けの 2 つの簡単な XML の例になります。
例3.38 簡単な BatchExecution XML
<batch-execution>
<insert out-identifier='outStilton'>
<org.drools.Cheese>
<type>stilton</type>
<price>25</price>
<oldPrice>0</oldPrice>
</org.drools.Cheese>
</insert>
</batch-execution>
例3.39 簡単な ExecutionResults XML
<execution-results>
<result identifier='outStilton'>
<org.drools.Cheese>
<type>stilton</type>
<oldPrice>25</oldPrice>
<price>30</price>
</org.drools.Cheese>
</result>
</execution-results>
stage オブジェクトを使用できます。これらを組み合わせると、より簡単にデータをセッション内やセッション外で移動できます。
CommandExecutor インターフェースを実装する stage があります。これを使用して、パイプラインスクリプトをステートフルまたはステートレスセッションにします。次のように設定を行います。
例3.40 CommandExecutor のパイプライン
Action executeResultHandler = PipelineFactory.newExecuteResultHandler();
Action assignResult = PipelineFactory.newAssignObjectAsResult();
assignResult.setReceiver( executeResultHandler );
Transformer outTransformer =
PipelineFactory.newXStreamToXmlTransformer(
BatchExecutionHelper.newXStreamMarshaller() );
outTransformer.setReceiver( assignResult );
KnowledgeRuntimeCommand cmdExecution =
PipelineFactory.newCommandExecutor();
batchExecution.setReceiver( cmdExecution );
Transformer inTransformer =
PipelineFactory.newXStreamFromXmlTransformer(
BatchExecutionHelper.newXStreamMarshaller() );
inTransformer.setReceiver( batchExecution );
Pipeline pipeline =
PipelineFactory.newStatelessKnowledgeSessionPipeline( ksession );
pipeline.setReceiver( inTransformer );
BatchExecutionHelper を使用して、command のカスタムコンバーターと新しい BatchExecutor ステージを持つ、特別に設定された XStream を提供します。
pipeline を使用するには、ResultHandler の実装を提供します。これは、pipeline が ExecuteResultHandler ステージを実行する時に呼び出されます。

図3.28 パイプライン ResultHandler
例3.41 簡単なパイプライン ResultHandler
public static class ResultHandlerImpl implements ResultHandler {
Object object;
public void handleResult(Object object) {
this.object = object;
}
public Object getObject() {
return this.object;
}
}例3.42 パイプラインの使用
ResultHandler resultHandler = new ResultHandlerImpl(); pipeline.insert( inXml, resultHandler );
BatchExecution を使用してオブジェクトを挿入し、クエリを実行します。以下の pipeline の例では XML 表現が使用されます。パラメーターはクエリに追加されています。
例3.43 XML へマーシャリングされた BatchExecution
<batch-execution>
<insert out-identifier="stilton">
<org.drools.Cheese>
<type>stilton</type>
<price>1</price>
<oldPrice>0</oldPrice>
</org.drools.Cheese>
</insert>
<query out-identifier='cheeses2' name='cheesesWithParams'>
<string>stilton</string>
<string>cheddar</string>
</query>
</batch-execution>
CommandExecutor は ExecutionResults を返し、pipeline コードスニペットによって処理されます。
例3.44 XML へマーシャリングされた ExecutionResults
<execution-results>
<result identifier="stilton">
<org.drools.Cheese>
<type>stilton</type>
<price>2</price>
</org.drools.Cheese>
</result>
<result identifier='cheeses2'>
<query-results>
<identifiers>
<identifier>cheese</identifier>
</identifiers>
<row>
<org.drools.Cheese>
<type>cheddar</type>
<price>2</price>
<oldPrice>0</oldPrice>
</org.drools.Cheese>
</row>
<row>
<org.drools.Cheese>
<type>cheddar</type>
<price>1</price>
<oldPrice>0</oldPrice>
</org.drools.Cheese>
</row>
</query-results>
</result>
</execution-results>
BatchExecutionHelper は事前設定された XStream を提供します。これを使用して一括実行のマーシャリングをサポートします (結果となる XML は上記の通り、メッセージ形式として使用できます)。Command Factory よりサポートされるコマンドのみに事前設定されたコンバーターが存在します。ユーザーオブジェクトに他のコンバーターを追加することもできます (特にサービスが関与する場合、ステートレスまたはステートフルナレッジセッションのスクリプティングに大変便利です)。
drools-transformer-xstream モジュールには drools-transformer-xstream と呼ばれる単体テストがあります。ルート要素は <batch-execution> と命名され、任意の数の command 要素を含めることが可能です。
例3.45 ルート XML 要素
<batch-execution> ... </batch-execution>
Command Factory によって提供されるコマンドに限定されます。最も基本的なものが <insert> 要素で、オブジェクトを挿入します。insert 要素の内容はユーザーオブジェクトで、XStream によって決まります。
例3.46 Insert
<batch-execution>
<insert>
...<!-- any user object -->
</insert>
</batch-execution>
insert 要素は out-identifier と呼ばれる属性を特徴とします。これは、挿入されたオブジェクトが結果ペイロードの一部として返されることを要求します。
例3.47 out 識別子コマンドを用いた挿入
<batch-execution>
<insert out-identifier='userVar'>
...
</insert>
</batch-execution>
out-identifier をサポートしません (org.domain.UserClass は XStream によるシリアライズが可能な例示のユーザーオブジェクトです)。
例3.48 Insert Elements コマンド
<batch-execution>
<insert-elements>
<org.domain.UserClass>
...
</org.domain.UserClass>
<org.domain.UserClass>
...
</org.domain.UserClass>
<org.domain.UserClass>
...
</org.domain.UserClass>
</insert-elements>
</batch-execution>
例3.49 Insert Elements コマンド
<batch-execution>
<set-global identifier='userVar'>
<org.domain.UserClass>
...
</org.domain.UserClass>
</set-global>
</batch-execution>
例3.50 Set Global コマンド
<batch-execution>
<set-global identifier='userVar1' out='true'>
<org.domain.UserClass>
...
</org.domain.UserClass>
</set-global>
<set-global identifier='userVar2' out-identifier='alternativeUserVar2'>
<org.domain.UserClass>
...
</org.domain.UserClass>
</set-global>
</batch-execution>
例3.51 Get Global コマンド
<batch-execution>
<get-global identifier='userVar1' />
<get-global identifier='userVar2' out-identifier='alternativeUserVar2'/>
</batch-execution>
例3.52 Query コマンド
<batch-execution>
<query out-identifier='cheeses' name='cheeses'/>
<query out-identifier='cheeses2' name='cheesesWithParams'>
<string>stilton</string>
<string>cheddar</string>
</query>
</batch-execution>
注記
<start-process> コマンドは任意のパラメーターも許可します。
例3.53 Start Process コマンド
<batch-execution>
<startProcess processId='org.drools.actions'>
<parameter identifier='person'>
<org.drools.TestVariable>
<name>John Doe</name>
</org.drools.TestVariable>
</parameter>
</startProcess>
</batch-execution
例3.54 Signal Event コマンド
<signal-event process-instance-id='1' event-type='MyEvent'> <string>MyValue</string> </signal-event>
例3.55 Complete Work Item コマンド
<complete-work-item id='" + workItem.getId() + "' >
<result identifier='Result'>
<string>SomeOtherString</string>
</result>
</complete-work-item>
例3.56 About Work Item コマンド
<abort-work-item id='21' />
注記
3.3.9. マーシャリング
MarshalerFactory を使用して stateful knowledge sessions のマーシャリングおよびアンマーシャリングを行います。

図3.29 MarshalerFactory
MarshalerFactory を使用する最も簡単な方法になります。
例3.57 簡単なマーシャラーの例
// ksession is the StatefulKnowledgeSession // kbase is the KnowledgeBase ByteArrayOutputStream baos = new ByteArrayOutputStream(); Marshaller marshaller = MarshallerFactory.newMarshaller( kbase ); marshaller.marshall( baos, ksession ); baos.close();
ObjectMarshalingStrategy インターフェースが追加されています。このインターフェースの 2 つの実装が提供され、ユーザーは独自の実装を追加できます。提供されている 2 つの実装は次の通りです。
- IdentityMarshalingStrategy
- SerializeMarshalingStrategy
SerializeMarshalingStrategy です (上記の例で使用されています)。これは、ユーザーインスタンス上で Serializable または Externalizable メソッドを呼び出しします。
IdentityMarshalingStrategy は ID がストリームに書き込まれる間に、各ユーザーオブジェクトに対して整数識別番号を作成し、マップに格納します。アンマーシャリングが行われている間、IdentityMarshalingStrategy マップへアクセスし、インスタンスを読み出します (そのため、IdentityMarshalingStrategy が使用されると、Marshaller インスタンスが生存している間はステートフルになり、識別子を作成し、マーシャリングを行いたい各オブジェクトへの参照を保持します)。IdentityMarshalingStrategy に使用するコードは次の通りです。
例3.58 IdentityMarshallingStrategy
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectMarshallingStrategy oms = MarshallerFactory.newIdentityMarshallingStrategy()
Marshaller marshaller =
MarshallerFactory.newMarshaller( kbase, new ObjectMarshallingStrategy[]{ oms } );
marshaller.marshall( baos, ksession );
baos.close();ObjectMarshalingStrategyAcceptor インターフェースも提供されています。各 Object Marshaling Strategy にはこのインターフェースが含まれています。マーシャラーは一連のストラテジーを持ち、ユーザーオブジェクトへ読み書きしようとすると、ストラテジーを繰り返し、ユーザーオブジェクトをマーシャリングする責任を受け入れるかどうか「依頼」します。提供される実装の 1 つは ClassFilterAcceptor と呼ばれます。これは、文字列とワイルドカードを使用してクラス名を照合できるようにします。デフォルトは *.* であるため、上記の例では使用される IdentityMarshalingStrategy にはデフォルトの *.* が含まれます。
例3.59 アクセプターを用いた IdentityMarshalingStrategy
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectMarshallingStrategyAcceptor identityAcceptor =
MarshallerFactory.newClassFilterAcceptor( new String[] { "org.domain.pkg1.*" } );
ObjectMarshallingStrategy identityStrategy =
MarshallerFactory.newIdentityMarshallingStrategy( identityAcceptor );
ObjectMarshallingStrategy sms = MarshallerFactory.newSerializeMarshallingStrategy();
Marshaller marshaller =
MarshallerFactory.newMarshaller( kbase,
new ObjectMarshallingStrategy[]{ identityStrategy, sms } );
marshaller.marshall( baos, ksession );
baos.close();注記

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.