この章の内容は次のとおりです。
この項では、ルール対応アプリケーションを作成する手順を示し、RuleSessionオブジェクトの使用方法について説明します。RuleSessionオブジェクトはパッケージoracle.rules.rlに含まれています。
RuleSessionコンストラクタは、引数がない場合、デフォルトのロケール、ロギングおよびDMSオプションが設定されたRuleSessionを戻します。
表4-1に、RuleSessionコンストラクタのプロパティを示します。
表4-1 RuleSessionのプロパティ
| プロパティ名 | プロパティ値 |
|---|---|
|
|
任意のロケールに対するロケール・オブジェクト。マップにない場合は、デフォルトのロケールが使用されます。 デフォルト値: JVMデフォルト・ロケール |
|
|
RuleSessionに関連付ける名前。 デフォルト値: 一意に生成された名前 |
|
|
ブール値。このプロパティが指定され、値が デフォルト値: |
|
|
ブール値。このプロパティが指定され、値が デフォルト値: |
|
|
このセッションをインスタンス化するアプリケーションまたはコンポーネントの名前を含む文字列。これは、DMSメトリックに対してのみ使用します。OC4Jでは、 デフォルト値: デフォルト値はありません。値が指定されない場合、そのコンポーネントはDMSメトリック階層に含まれません。 |
outputWriterプロパティは、println、watchおよびshowの出力先を決定します。
rulesetNameプロパティは、明示的にルールセット名を指定せずに、RL文が実行されるイベント内にルールセットを設定します。デフォルトのrulesetNameはmainです。
executeRulesetメソッドは、指定のルールセット・テキスト(Stringまたはjava.io.Readerとして指定)を解析して実行します。
callFunctionメソッドは、名前付きRL関数(組込みRL関数または以前にexecuteRulesetメソッドの1つを使用してパラメータなしで定義した関数)を起動し、その結果を戻します。単一の引数を取る関数は、callFunctionWithArgumentメソッドを使用して起動できます。任意の数の引数を取る関数は、callFunctionWithArgumentListまたはcallFunctionWithArgumentArrayメソッドを使用してコールできます。引数のリストまたは配列には、各RL関数パラメータのJavaオブジェクトが記載されている必要があります。
表4-2に、引数をRL関数に渡すためにJavaオブジェクト型をRL型に変換する方法、およびRL関数の戻り値をJavaに渡すためにRL型をJava型に変換する方法を示します。
表4-2 RLからJavaオブジェクトへの変換
| Javaクラス | RL型 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RuleSessionの解析メソッドと実行メソッドでは、RLExceptionがスローされる場合があります。getMessageメソッドは、書式化されたエラー・メッセージを戻します。このエラー・メッセージには、エラーの説明、RLソース(mainまたはインクルードされたURL)、行番号および列番号が含まれます。これらのエラー・コンポーネントには、個別にアクセスすることもできます。RLExceptionは、別のエラー(通常はThrowableオブジェクト)によって発生する場合があります。この場合も、基本的なエラー原因(ある場合)にアクセスできます。
例外は、パッケージoracle.rules.rl.exceptionsに含まれます。次の階層に示すように、RLExceptionクラスには、例外の種類を分類したサブクラスが多数あります。
RLException
ParseException - a syntax error
TypeCheckException - a semantic error
ArrayException - array expected
AssignmentException - invalid assignment target
ConstructorException - can't find constructor for Java class
ContextException - construct invalid in given context
ConversionException - can't convert between given types
FinalClassException - attempt to extend a final fact class
InvocationException - illegal function or method invocation
HiddenPropertyException - fact class for subclass attempted to expose a hidden property or vice versa
MemberException - property or method not a member of class
MultipleDefinitionException - symbol defined more than once
OperationException - operator applied to wrong types. For example, String * String
UndefinedException - symbol is not defined
VisibilityException - class or member referenced outside of defining ruleset or package is not public
RLRuntimeException - runtime error
RLXPathException - error in assertXPath function
RLXmlNameException - error in xml identifier syntax
EngineException - internal rule engine error
JavaException - an invoked Java method threw an exception, call getCause() to access the exception
RLArithmeticException - an RL arithmetic operation resulted in a divide by zero.
RLArrayIndexOutOfBoundsException - an attempt was made to index into an array with an index outside the
allocated array
RLArrayStoreException - an attempt has been made to store the wrong type of object into an RL array of
objects
RLClassCastException - in an RL expression, at attempt has been made to cast an object to a subclass of
which it is not an instance
RLCloneNotSupportedException - a property of an object asserted as a fact appeared to be cloneable but did
not implement the clone method
RLIllegalArgumentException - an attempt was made to pass an illegal argument to a builtin RL function or to
a rule engine Java method
RLNegativeArraySizeException - an attempt was made to allocate an array with a negative size
RLNullPointerException - an RL expression attempted to dereference a null object or null array reference
次の例外は、RLRuntimeExceptionまたはTypeCheckExceptionのいずれかで常にラップされます。
FactClassException: ファクト・クラスの定義が遅すぎます(ファクト・コンテキストにはサブクラスがすでに存在しています)。
MultipleInheritanceException: ファクト・クラス宣言でサポートしているのは単一の継承のみです。
RuleSessionメソッドの起動でParseExceptionまたはTypeCheckExceptionがスローされても、RuleSessionの状態には影響を与えません。Javaアプリケーション(たとえば、対話型のコマンドライン)では、これらの例外を検出し、RuleSessionの使用を続行できます。
RuleSessionメソッドの起動でRLRuntimeExceptionがスローされた場合は、RuleSessionの状態に影響を与える可能性があり、アプリケーションでRuleSessionを処理できない状態になる場合があります。堅牢なアプリケーションの場合は、RLでRLRuntimeExceptionを検出し、例外がスローされた近辺でリカバリするように試みます。
その他の例外は、多くの場合、アプリケーションで処理できない重大な問題を示します。
RLクラスは、Javaクラスと同様にRLプログラムで使用できます。new、instanceofおよびcastの演算子は、両方のクラスで使用できます。ただし、Javaプログラムに渡されたRLクラスのインスタンスは、実際にはoracle.rules.rl.RLObjectのインスタンスです。Javaプログラムでは、RLObjectを調べるためにRLClass、RLPropertyおよびRLArrayクラスを使用できます。使用方法は、java.lang.Class、java.lang.reflect.Fieldおよびjava.lang.Arrayクラスを使用してjava.lang.Objectを反映する場合と同じです。RLCLass、RLPropertyおよびRLArrayは、パッケージoracle.rules.rlに含まれます。
XLinkオブジェクトは、assertXPath関数によって作成され、ファクトとしてアサートされます。RLルールでは、XLinkを使用して、assertXPathによってアサートされた要素の階層を推論できます。
Oracle Business Rulesを使用してルール対応プログラムを作成したときの一般的な疑問は、「評価の結果を取得する方法は?」です。
この項では、ルール・エンジンからルール評価の結果を抽出または表示する方法を説明します。
内容は次のとおりです。
|
関連項目: 『Oracle Business Rulesユーザーズ・ガイド』の第3章11項の「ルールの起動」 |
この項で使用する例は、高速道路の事故通知システムを示しています。それぞれの例は、ルール・エンジンの評価結果にアクセスするための異なる方法を示しています。これらの例では、2つのJavaクラスtraffic.TrafficIncidentおよびtraffic.IncidentSubscriptionを使用します。
|
注意: サンプルのtraffic.*クラスは、Oracle Business Rulesに同梱されていません。 |
TrafficIncidentクラスは、交通状況に影響を与える事故の情報を表し、次のプロパティが含まれています。
どの高速道路か
上りか下りか
事故の種類
事故発生時刻
渋滞の見積時間(分単位)
IncidentSubscriptionクラスは、特定の高速道路における事故の通知へのサブスクリプションを記述し、次のプロパティが含まれています。
サブスクライバ: サブスクライバの名前
該当する高速道路
上りか下りか
この例では、高速道路で交通状況に影響を与える事故が発生したとき、これらのクラスを使用してTrafficIncidentオブジェクトをアサートし、ルール評価によって通知の受信者を判断します。
例に示すsessオブジェクトはRuleSessionで、事故通知の多数のサブスクリプションがアサートされます。単純化するために、TrafficIncidentオブジェクトは永続的でないことを前提にしています。実際には、このオブジェクトはアサート対象イベントを表し、その時点で登録されているサブスクライバにのみ通知が送信されます。
この例で使用するクラスはすべてJavaクラスです。ただし、RLクラスの反映を使用して、JavaでRLクラスのインスタンスを操作することもできます。
|
関連項目: ドキュメントについては、oracle.rules.rlパッケージにあるRLClass、RLObject、RLPropertyおよびRLArrayクラスに関するJavadocを参照してください。RLオブジェクト、つまりRLクラスのインスタンスを使用すると、Javaオブジェクトと同様に、ルール・エンジンの結果を保持できます。 |
この方法は、結果用のコンテナをアサートする方法と同じです。ただし、コンテナではなくオブジェクトを使用して、ルール・エンジンの外部にあるリソースに作用します。たとえば、予定の作業をキューに挿入したりスケジュールする場合、データベースを更新する場合、メッセージを送信する場合が該当します。結果を導出するには、アクションでアクセス可能な任意のJavaメソッドを起動できます。コンテナを使用する場合と同様に、外部リソースにアクセスするためにこの例で使用されているオブジェクトは、その内容が推論の対象でないため、再度アサートされることはありません。
例4-1に示すIncidentDispatcherオブジェクトは、アサートされて通知の配信に使用されます。
例4-1 外部リソースを使用した結果の取得
rule incidentAlert
{
if (fact TrafficIncident ti &&
fact IncidentSubscription s &&
s.highway == ti.highway &&
s.direction == ti.direction &&
fact IncidentDispatcher dispatcher)
{
dispatcher.dispatch(s.subscriber, ti);
}
}
例4-2に示すJavaコードは、IncidentDispatcherおよびTrafficIncidentをアサートし、ルール・エンジンを起動します。これは、推論の対象となるオブジェクトを使用しても実行できます。ただし、この場合は、ルール起動の無限ループを回避するために、ルール条件のテストが必要になります。
例4-2 外部リソースを使用した結果の例
sess.callFunctionWithArgument("assert", new IncidentDispatcher());
// 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);
sess.callFunctionWithArgument("assert", ti);
sess.callFunction("run");