Oracle Business Rules ユーザーズ・ガイド 10g(10.1.3.1.0) B31866-02 |
|
この章では、Rule Authorの高度な機能の一部を使用する方法について説明します。
この章の内容は次のとおりです。
この項では、Rule Authorを使用して、メッセージの一部を置換する変数を追加します。このメッセージは、第2章で作成したJava版How-Toで出力するメッセージです。Oracle Business Rulesで使用する変数は、Javaにおけるパブリックな静的変数に類似しています。変数は、定数または変更可能に指定できます。
変数を追加する手順は、次のとおりです。
(アイテムが見つかりません)
を含む表が表示されます。これは、変数が何も定義されていないことを示します。
DeclineMessage
と入力します。
Decline Message
と入力します。
String
を選択します。
"Rental declined "
と入力します。 式の作成を支援するウィザードを使用するには、編集アイコンをクリックして、ウィザードを表示します。
Rule Authorの変数を作成する際の注意:
カスタマイズ可能ルールで、フィールドへの許容値を特定の値セットに制約する(たとえば、値の範囲を指定する)場合は、Rule Authorの制約定義を使用できます。
Rule Authorでは、表3-1に示すように、3つのタイプの制約定義がサポートされています。
制約タイプ | 説明 |
---|---|
範囲 |
数値の範囲を指定します。 |
列挙 |
指定可能な値のリストを指定します。 |
正規表現 |
文字列値が準拠する正規表現を指定します。この制約での正規表現の構文は、Javaの正規表現の定義に従います。 |
この項の例では、制約を定義してCarRentalディクショナリのUnderAgeルールに追加します。
範囲制約を定義する手順は、次のとおりです。
validAgeRange
と入力します。
Range
を選択します。これにより、「制約」ページの表示が更新されて、「開始値(数値)」と「終了値(数値)」の2つの新規フィールドが表示されます。
15
を入力します。
99
を入力します。
次に、validAgeRange
をUnderAgeルールに追加することによってこの制約を使用します。
UnderAgeルールでこの制約を使用する手順は、次のとおりです。
validAgeRange
(「値」列の2番目のボックス)を選択します。
「カスタマイズ」タブを使用して、Rule Author では指定した範囲の値のみを入力でき、無効な入力は拒否されることを確認します。
この例では、CarRentalルールを拡張するDecisionというRLファクトを作成します。RLファクトには、driverName
、type
およびmessage
という3つの文字列
型のメンバーがあります。RLファクトDecisionを作成する手順は、次のとおりです。
Decision
と入力します。
Car rental decision
と入力します。 図3-3を参照してください。
driverName
と入力します。
String
を選択します。
driver name
と入力します。
type
と入力します。
String
を選択します。
decision type
と入力します。
message
と入力します。
String
を選択します。
message for decision
と入力します。
DM.Decision
が表示されます。Oracle Business Rulesでは、組込み関数またはユーザー定義関数をルールの条件とアクションに使用できます。この項では、Rule Authorを使用してshowDecision
という関数を定義します。この関数を使用すると、Java版How-Toに関する結果を出力できます。
注意2: Rules SDKから生成されたRL Languageの場合、たとえばRule Authorを使用してルールを作成すると、グローバル変数がRL Language関数で直接参照されないことがあります。詳細は、D.2項「RL関数で使用できないグローバル変数」を参照してください。 |
showDecision
関数を定義する手順は、次のとおりです。
showDecision
と入力します。
Show Decision
と入力します。void
(デフォルト値)を選択します。
decision
と入力します。
Decision made for driver
と入力します。
Car rental decision
を選択します。
DM.println( "Rental decision is " + decision.type + " for driver " + decision.driverName + " for reason " + decision.message);
DM.showDecision
が表示されます。
3.3項で説明したように新規RLファクトDecision
を作成し、新規RL関数DM.showDecision
を作成した後は、UnderAgeルールを更新して新規Decisionファクトを作成するアクションを提供できます。DecisionファクトをshowDecision
関数で使用するには、Decisionファクトをチェックし、showDecision
関数を使用して結果を表示するためのアクションを提供する新規ルールを作成する必要があります。
ルールにアクションを追加する場合、アクションにはパターン一致が関連付けられます。ルールの「if」部が一致すると、ルール・エンジンによって「then」部がアクティブになり、ルールに関連付けられたアクションの実行が準備されます。表3-2は、ルールを作成するときに使用できるアクションのタイプを示しています。
データ・モデル内のオブジェクト(インポートするクラスまたはパッケージを含む)を表示する手順は、次のとおりです。
レンタカー・サンプルでは、インポートされたcarrental.Driver
クラスを含む表が表示されます。
表3-3および表3-4は、Javaファクトのプロパティおよびメソッドの表のフィールドを説明しています。
プロパティ、クラスまたはメソッドをRule Authorの選択ボックスで参照可能にするかどうかを指定できます(プロパティ、クラスまたはメソッドが含まれる選択ボックスは、「ルールセット」タブでルールを作成するときに表示されます)。
Javaオブジェクトの参照可能性を削除する手順は、次のとおりです。
JavaプロパティまたはJavaメソッドの参照可能性を削除する手順は、次のとおりです。
Rule Authorの選択ボックスに、スーパークラス・チェーン内の指定したメソッドまたはプロパティの1レベル上のメソッドまたはプロパティを表示するには、「Javaファクト」ページで、そのメソッドまたはプロパティの「拡張」ボックスを選択します。この「拡張」ボックスは、「プロパティ」領域または「メソッド」領域の「拡張」フィールドに表示されます。「拡張」ボックスは、スーパークラスがあるメソッドまたはプロパティに対してのみ表示されます(Rule Authorでは、プリミティブ型には「拡張」ボックスは表示されません)。
Rule Authorでは、「RL」タブを使用して、RL Languageテキストを表示できます。このテキストは、データ・モデルおよびディクショナリ・データに関連付けられたルールセットを示します。
RL Languageテキストを生成、表示、およびチェックする手順は、次のとおりです。
Rule Authorでは、ディクショナリ・プロパティを使用して、式で使用するデフォルトの式タイプを指定して、ロギングのオプションを指定できます。
内容は次のとおりです。
ディクショナリ・プロパティを構成するには、次の手順を実行します。
「アドバンスト・テスト式」チェック・ボックスによって、テスト式に対するRule Authorの式モードが拡張に変更されます。このテスト式は、ルールのパターンを編集するときに表示されます(図3-7を参照)。ルール条件のテストには、数学的演算や論理積が伴う場合があります。Rule Authorには、このような複雑な式の定義をサポートする拡張式モードがあります。
パターンを初めて作成するときのテスト式モードは、「プロパティ」ページで設定した「アドバンスト・テスト式」プロパティによって決まります。「アドバンスト・テスト式」チェック・ボックスを選択すると、すべての新規パターンにアドバンスト・テスト式モードが適用されます。この設定は、ディクショナリの保存時に保持されます。この場合は、ディクショナリのロード時に、すべてのパターンがアドバンスト・テスト式モードで作成されます。作成後のパターンは、テストの有無に関係なく、テスト式モードに永続的に関連付けられます。したがって、パターンに関連するテスト式モードは変更できません。
単一ルール内で、基本式モードと拡張式モードで作成した両方のパターンを使用できます。
「ロギング」ボックスによって、ロギングのオプションが指定されます。このオプションは、Rule Authorの問題をレポートする必要がある場合に便利です。ロギングを指定するには、「ロギング」チェック・ボックスを選択した後、次のログ・ファイル・プロパティを選択します。
<log_file_name>
.
<last_8_session_id>
という名前のファイルにログが保存されます。たとえば、ログ・ファイル名にRALog
を指定し、セッションIDの最後の8桁が11223344
の場合は、RALog.11223344
というファイルが作成されます。ログ・ファイルが指定されていない場合、ログは、RuleAuthor.
<last_8_session_id>
という名前のファイルに保存されます。
ロギング・オプションの指定が終了した後、「更新」をクリックします。
この項では、ディクショナリのバージョンまたはディクショナリ全体を削除する方法について説明します。
個々のディクショナリ・バージョンを削除する手順は、次のとおりです。
特定のディクショナリ・バージョンを削除する場合は、「ディクショナリ・バージョンの選択」セクションでディクショナリとバージョンを選択し、「バージョンの削除」をクリックします。
ディクショナリ全体(およびそのすべてのバージョン)を削除する場合は、「ディクショナリ全体の選択」セクションでディクショナリを選択し、「削除」をクリックします。
Rule Authorには、ディクショナリの特定バージョンまたはディクショナリ全体をインポートできます。手順は次のとおりです。
ディクショナリがローカルにある場合は、最初の箇条書きのセクションを使用してその場所を指定します。ディクショナリのパスを手動で入力するか、または「参照」ボタンをクリックしてディクショナリを選択できます。
ディクショナリが(Rule Authorが実行されていない)別のマシンにある場合は、そのサーバー上のディクショナリのフルパスを指定する必要があります。
ディクショナリ全体をエクスポートする手順は、次のとおりです。
ディクショナリを選択して「ダウンロード」をクリックすることもできます。これによって、エクスポート済アーカイブへのリンクが「ディクショナリのエクスポート」ページに作成されます。次に、リンクをクリックすると、ブラウザを使用して、選択した場所にアーカイブをダウンロードできます(図3-8を参照)。
特定のディクショナリ・バージョンをエクスポートする手順は、次のとおりです。
ディクショナリとバージョンを選択して、「ダウンロード」をクリックすることもできます。これにより、「ディクショナリのエクスポート」ページのエクスポート済アーカイブへのリンクが作成されます。次に、ブラウザを使用して、選択した場所にアーカイブをダウンロードできます(図3-8を参照)。
Rule Authorでは、テスト・ルールセット機能により、RL関数を使用してルールセットをテストできます。選択したルールセットとそのルールセットに関連付けられたデータ・モデルがルール・セッションで実行され、ルールを実行するユーザー定義関数がコールされます。
テスト・ルールセット機能を使用する手順は、次のとおりです。
Javaクラスの場合は、次のディレクトリにJARファイルを挿入してから、OC4Jを再起動してクラスパスにクラスを追加できます。
$ORACLE_HOME/j2ee/home/applications/ruleauthor/lib
Javaクラスを共有ライブラリとして組み込むこともできます。その結果、Rule Authorでは他のアプリケーションとクラスを共有できるようになります。これを実行するには、Enterprise Managerにログインして次の操作を実行します。
test
と入力します。
void
のままにします。
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat( "MM/dd/yyyy" ); assert (new carrental.Driver( "d111", "Dave", 50, "sports", "full", sdf.parse ("10/1/1969"), 0, 1, true )); assert (new carrental.Driver( "d222", "Abe", 15, "truck", "provisional", sdf.parse ("8/1/2004"), 0, 0, true )); assert (new carrental.Driver( "d333", "Lance", 44, "motorcycle", "full", sdf.parse ("6/1/2004"), 0, 1, true )); pushRuleset ("vehicleRent"); run();
この関数は、複数のファクトをアサートし、vehicleRent
ルールセットをルールセット・スタックに追加し、run()
をコールします。
ロギングを有効にするには、watchFacts()
関数またはwatchActivations()
関数をコールできます。
DM.test
が保存されます。
vehicleRent
ルールセットが使用可能であることを確認できます。このルールセットは、第2章で作成したものです。
vehicleRent
ルールセットを選択して「選択したルールセット」列に移動します。
選択したルールセットに対してRL Languageコードが生成され、ルール・セッションに挿入されます。次に、選択したテスト関数がコールされます。関数の出力が画面に表示されます(図3-10を参照)。
ルール対応プログラムでは、通常、次の手順でルールを起動します。
この項では、RL関数を使用してルールの起動をカプセル化するためのベスト・プラクティスについて説明します。ルールを起動する3つの方法について説明します。これらの方法の主な相違点は、結果を取得する方法の詳細にあります。この項では、getSubscribers
というサンプルRL関数を使用します。このルーチンを使用すると、getSubscribers
メソッドをコールするルール対応プログラムという観点において、ルール起動の各方法が同じであるように見えます。
内容は次のとおりです。
この項で使用する例は、高速道路の事故通知システムを示しています。それぞれの例は、ルール・エンジンの評価結果にアクセスするための異なる方法を示しています。これらの例では、2つのJavaクラスtraffic.TrafficIncident
およびtraffic.IncidentSubscription
を使用します。
TrafficIncident
クラスは、交通状況に影響を与える事故の情報を表し、次のプロパティが含まれています。
IncidentSubscription
クラスは、特定の高速道路における事故の通知へのサブスクリプションを記述し、次のプロパティが含まれています。
この例では、高速道路で交通状況に影響を与える事故が発生したとき、これらのクラスを使用してTrafficIncident
オブジェクトをアサートし、ルール評価によって通知の受信者を判断します。
例に示されたsess
はRuleSession
オブジェクトで、事故通知の多数のサブスクリプションがアサートされます。単純化するために、TrafficIncident
オブジェクトは永続的でないことを前提にしています。実際には、このオブジェクトはアサート対象イベントを表し、その時点で登録されているサブスクライバにのみ通知が送信されます。
結果の累計にはグローバル変数を使用することが最良の方法です。この方法を使用すると、3.12.3項および3.12.4項に示す方法よりも単純なルール条件が生成されます。
例3-1は、TrafficIncident
オブジェクトをアサートし、Map
オブジェクトによってグローバル変数を初期化し、Rules Engineを起動して、結果のMap
オブジェクトを返すgetSubscribers
関数を示しています。
Map alerts = null; function getSubscribers(TrafficIncident ti) returns Map { try { alerts = new HashMap(); assert(ti); run(); return alerts; } finally { retract(ti); alerts = null; } } rule incidentAlert { if (fact TrafficIncident ti && fact IncidentSubscription s && s.highway == ti.highway && s.direction == ti.direction) { alerts.put(s.subscriber, ti); } } }
例3-2に、getSubscribers
関数を起動し、結果を出力するJavaコードを示します。
// An accident has happened TrafficIncident ti = new TrafficIncident(); ti.setHighway("I5"); ti.setDirection("south"); ti.setIncident("accident"); ti.setWhen(new GregorianCalendar(2005, 1, 25, 5, 4)); ti.setDelay(45); Map alerts = (Map)sess.callFunctionWithArgument("getSubscribers", ti); Iterator iter = alerts.keySet().iterator(); while(iter.hasNext()) { String s = (String)iter.next(); System.out.println("Alert " + s + " : " + alerts.get(s)); }
コンテナ・オブジェクト方法では、1つ以上のオブジェクトが作業メモリーにアサートされ、結果のコンテナとして機能します。オブジェクトをアサートするRL Languageコードによって、そのオブジェクトの参照が常に使用できるように保持されます。起動されたルールは、結果をコンテナに追加できます。コンテナ・オブジェクトは、Javaコレクション・クラスの1つか、特定のアプリケーション固有のコンテナ・オブジェクトの場合があります。ルール評価が完了すると、コンテナ・オブジェクトを検査して結果にアクセスできます。
例3-3 は、java.util.Map
オブジェクトを使用し、サブスクライバ(key
)と事故(value
)をMap
オブジェクトに追加するgetSubscribers
関数を示しています。getSubscribers
関数は、Map
オブジェクトおよびTrafficIncident
オブジェクトをアサートし、Rules Engineを起動して、結果をMap
オブジェクトに返します。
function getSubscribers(TrafficIncident ti) returns Map { Map alerts = new HashMap(); try { assert(alerts); assert(ti); run(); return alerts; } finally { retract(alerts); retract(ti); } } rule incidentAlert { if (fact TrafficIncident ti && fact IncidentSubscription s && s.highway == ti.highway && s.direction == ti.direction && fact Map alerts) { alerts.put(s.subscriber, ti); } } }
例3-2に、getSubscribers
関数を起動し、結果を出力するJavaコードを示します。
判断オブジェクト方法では、1つ以上のオブジェクトがルール・エンジンの作業メモリーにアサートされ、オブジェクト参照は(getSubscribers
関数の)RL Languageに保持されます。ルール評価プロセスによって、これらのオブジェクトの1つ以上が更新されます。これらのオブジェクトは、ルール評価による結果の判定後に検査されます。
例3-4では、TrafficIncident
クラスが、通知する必要のあるサブスクライバの更新済java.util.Set
を保持するように変更されます。TrafficIncident
オブジェクトは判断されるために再アサートされます。同じサブスクリプションに対するルール起動の無限ループを回避するには、subscribed
メソッドを使用して、一致した事故をテストする必要があります。このメソッドによってループが防止されます。subscribed
メソッドは、一致するTrafficIncident
オブジェクトにサブスクライバがすでに追加されている場合はtrue
を戻します。これは、ルール・プログラミングの共通の特徴です。ルール・アクションは判断されるファクトを更新します。不要な追加起動を回避するには、その更新の存在の有無をチェックする条件にテストを追加します。
例3-4は、TrafficIncident
オブジェクトをアサートし、Rules Engineを起動して、結果のMap
オブジェクトを作成して返すgetSubscribers
関数を使用するコードを示しています。
function getSubscribers(TrafficIncident ti) returns Map { try { assert(ti); run(); Map alerts = new HashMap(); for (Iterator iter = ti.subscribers(); iter.hasNext(); ) { alerts.put(iter.next(), ti); } return alerts; } finally { retract(ti); } } rule incidentAlert { if (fact TrafficIncident ti && fact IncidentSubscription s && s.highway == ti.highway && s.direction == ti.direction && !ti.subscribed(s.subscriber)) { ti.addSubscriber(s.subscriber); assert(ti); } } }
例3-2に、getSubscribers
関数を起動し、結果を出力するJavaコードを示します。
|
Copyright © 2005, 2006, Oracle Corporation. All Rights Reserved. |
|