ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Application Development FrameworkによるFusion Webアプリケーションの開発
12c (12.1.2)
E48099-02
  目次へ移動
目次

前
 
次
 

12 プログラムによる検証とビジネス・ルールの実装

この章では、ADFエンティティ・オブジェクトのイベントと機能を使用して、ビジネス・ルールをOracle ADFアプリケーション内でプログラム的に実装する方法について説明します。また、setterメソッドを使用したエンティティ行への移入など、カスタム検証コードの起動方法についても説明します。

この章には次の項が含まれます:

12.1 プログラム的なビジネス・ルールについて

内蔵された宣言型検証機能を補完するため、エンティティ・オブジェクトとビュー・オブジェクトにはJavaコードを使用してカプセル化されたビジネス・ロジックをプログラミングによって実装できる操作可能なメソッド・バリデータといくつかのイベントがあります。これらの概念を、図12-1に示します。

図12-1 プログラム的なビジネス・ロジックにおける主要なエンティティ・オブジェクトの機能とイベント

この図は、エンティティ・オブジェクト機能を示しています。

注意:

新規行と変更された行のみがトランザクション検証の対象となります。削除された行はトランザクションの一部ですが、検証には含まれません。

プログラム的なビジネス・ルールをコーディングする場合、検証サイクルを正確に把握しておくことが重要です。詳細は、11.2項「検証サイクルの理解」を参照してください。


12.1.1 プログラム的なビジネス・ルールのユースケースと例

ほとんどの検証は基本的な宣言的操作で実装できますが、メソッド・バリデータを使用してカスタム検証コードを起動することにより、必要に応じてビジネス・ドメイン・レイヤーにより複雑なビジネス・ルールを実装できます。

プログラム的なビジネス・ルールを使用する場合としては、次の例があります。

  • データベース順序からの属性値のデフォルト設定

  • 複雑な計算から導出された値の割当て

  • エンティティ・オブジェクトに対する保留中の変更の取消し

  • 現在のユーザー・セッションに関する情報のアクセスと格納

  • 属性の条件付き更新可能性の判断

12.1.2 プログラム的なビジネス・ルールの追加機能

プログラム的な検証を使用する前に、他のOracle ADF機能を理解しておくと役立つ場合があります。次に、関連する他の機能へのリンクを示します。

12.2 メソッド・バリデータの使用

メソッド・バリデータは、独自のJavaコードを使用した宣言的な検証規則とGroovyスクリプト式を補完する主要な手段です。メソッド・バリデータでは、独自の検証メソッド内に記述したJavaコードが、エンティティ・オブジェクト検証サイクルにおいて適切なタイミングでトリガーされます。メソッド・バリデータにより、属性またはエンティティ全体で、様々な型の検証をコーディングできます。

それぞれがコード内の異なるメソッド名をトリガーしていれば、任意の数の属性レベルまたはエンティティレベルのメソッドを追加できます。すべての検証メソッド名はvalidateというワードで開始する必要があります。ただし、この規則にさえ従っていれば、機能を明確に示す任意の方法で名前を付けることができます。属性レベルのバリデータでは、メソッドはエンティティ属性と同じ型の引数を1つだけ取ります。エンティティレベルのバリデータでは、メソッドは引数を取りません。メソッドはパブリックで、ブール値を返す必要があります。メソッドからfalseが返されると、検証は失敗します。


注意:

これらの規則を知っておくことは必要ですが、JDeveloperを使用してメソッド・バリデータを作成する場合、そのクラスの正しいインタフェースが作成されます。


実行時には、メソッド・バリデータにより、エンティティ属性がエンティティ・オブジェクト・クラスで実装されているメソッドに渡されます。

例12-1では、メソッドは大文字で始まり、NULL値で例外をスローする文字列、空の文字列および大文字で始まらない文字列を受け取ります。

例12-1 先頭が大文字の場合に検証を行うメソッド

public boolean validateIsCapped(String text)
{
  if (text != null && 
      text.length() != 0 && 
      text[0] >= 'A' && 
      text[0] <= 'Z')
  {
    return true;
  }
}

12.2.1 属性レベルのメソッド・バリデータの作成方法

メソッド・バリデータの使用は、宣言的検証規則をプログラム的に補完する手段です。

始める前に:

メソッド・バリデータに関する知識があると役立つ場合があります。詳細は、12.2項「メソッド・バリデータの使用」を参照してください。

また、他の検証機能を使用して追加できる機能についても理解しておくと役立ちます。詳細は、12.1.2項「プログラム的なビジネス・ルールの追加機能」を参照してください。

属性レベルのメソッド・バリデータを作成するには:

  1. 「アプリケーション」ウィンドウで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタで、「Java」ナビゲーション・タブをクリックします。

    Javaページには、そのエンティティ・オブジェクトに対して現在有効なJava生成オブジェクトが表示されます。エンティティ・オブジェクトにカスタム・エンティティ・オブジェクト・クラスがない場合は、Methodバリデータの追加前に生成しておく必要があります。カスタムJavaクラスを生成するには、「編集」アイコンをクリックし、次に「エンティティ・オブジェクト・クラスの生成」を選択し、「OK」をクリックして、*.javaファイルを生成します。

  3. 「ビジネス・ルール」ナビゲーション・タブをクリックし、「属性」セクションを開いて、検証する属性を選択します。

  4. 「新規」アイコンをクリックし、検証規則を追加します。

  5. 「検証ルールの追加」ダイアログの「ルール・タイプ」ドロップダウン・リストで「メソッド」を選択します。

    図12-2 属性レベルのメソッド・バリデータの追加

    「検証ルールの追加」ダイアログの図

    「検証ルールの追加」ダイアログに、属性レベルの検証メソッドで期待されるメソッド・シグネチャが表示されます。次のいずれかを選択できます。

    • エンティティ・オブジェクトのカスタムJavaクラスに、適切なシグネチャのあるメソッドがすでに存在する場合、リストに表示されます。これは「メソッドの作成と選択」チェック・ボックスの選択を解除した後に選択できます。

    • 「メソッドの作成と選択」チェック・ボックスを選択したままにすると(図12-2を参照)、validateから始まるどのようなメソッド名でも「メソッド名」ボックスに入力できます。「OK」をクリックすると、適切なシグネチャとともに、メソッドがエンティティ・オブジェクトのカスタムJavaクラスに追加されます。

  6. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などのルールの実行基準を入力します。詳細は、11.6項「検証実行のトリガー」を参照してください。

  7. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。

    詳細は、11.7項「検証エラー・メッセージの作成」を参照してください。

12.2.2 属性レベルのメソッド・バリデータを作成するときに行われる処理

メソッド・バリデータを新たに追加すると、JDeveloperでは新しい検証ルールを反映するように、XMLドキュメントが更新されます。メソッドの作成を指定した場合、そのメソッドはエンティティ・オブジェクトのカスタムJavaクラスに追加されます。例12-2は、オーダーのOrderShippedDateが現在月の日付であることを確認する、簡単な属性レベルの検証規則を示しています。メソッドには、対応する属性と同じ型の引数が与えられ、その条件付きのロジックはこの入力パラメータの値に基づいています。属性バリデータの起動時、属性値は対象となる新しい新しい値にはまだ設定されていません。したがって、getOrderShippedDate()メソッドをOrderShippedDate属性に対する属性バリデータ内でコールしても、クライアントが設定しようとしている候補値ではなく、属性の現在の値が返されます。

例12-2 簡単な属性レベルのメソッド・バリデータ

public boolean validateOrderShippedDate(Date  data) {
  if (data != null && data.compareTo(getFirstDayOfCurrentMonth()) <= 0) {
    return false;
  }
  return true;
}

注意:

compareTo()メソッドの戻り値は、2つの日付が等しい場合はゼロ(0)、最初の日付が次の日付より前の場合はマイナス1(-1)、最初の日付が次の日付より後の場合はプラス1 (1)となります。


12.2.3 エンティティ・レベルのメソッド・バリデータの作成方法

エンティティ・レベルのメソッド・バリデータは、有効範囲がより広く、単一の属性ではなくエンティティ全体が範囲になる点を除けば、属性レベルのメソッド・バリデータと似ています。

さらに、エンティティレベルのメソッド・バリデータを使用している場合は、バリデータの実行をトランザクションの時間まで遅延できます。

始める前に:

メソッド・バリデータに関する知識があると役立つ場合があります。詳細は、12.2項「メソッド・バリデータの使用」を参照してください。

また、他の検証機能を使用して追加できる機能についても理解しておくと役立ちます。詳細は、12.1.2項「プログラム的なビジネス・ルールの追加機能」を参照してください。

エンティティ・レベルのメソッド・バリデータを作成するには:

  1. 「アプリケーション」ウィンドウで、目的のエンティティ・オブジェクトをダブルクリックします。

  2. 概要エディタで、「Java」ナビゲーション・タブをクリックします。

    Javaページには、そのエンティティ・オブジェクトに対して現在有効なJava生成オブジェクトが表示されます。エンティティ・オブジェクトにカスタム・エンティティ・オブジェクト・クラスがない場合は、Methodバリデータの追加前に生成しておく必要があります。カスタムJavaクラスを生成するには、「編集」アイコンをクリックし、次に「エンティティ・オブジェクト・クラスの生成」を選択し、「OK」をクリックして、*.javaファイルを生成します。

  3. 「ビジネス・ルール」ナビゲーション・タブをクリックして「エンティティ」ノードを選択し、「新規」アイコンをクリックして検証ルールを追加します。

  4. 「検証ルールの追加」ダイアログの「ルール・タイプ」ドロップダウン・リストで「メソッド」を選択します。

    「検証ルールの追加」ダイアログに、エンティティレベルの検証メソッドで期待されるメソッド・シグネチャが表示されます。次のいずれかを選択できます。

    • エンティティ・オブジェクトのカスタムJavaクラスに、適切なシグネチャのあるメソッドがすでに存在する場合、リストに表示されます。これは「メソッドの作成と選択」チェック・ボックスの選択を解除した後に選択できます。

    • 「メソッドの作成と選択」チェック・ボックスを選択したままにすると(図12-3を参照)、validateから始まるどのようなメソッド名でも「メソッド名」ボックスに入力できます。「OK」をクリックすると、適切なシグネチャとともに、メソッドがエンティティ・オブジェクトのカスタムJavaクラスに追加されます。

  5. 必要に応じて、「検証実行」タブをクリックして、依存属性や事前条件式などのルールの実行基準を入力します。詳細は、11.6項「検証実行のトリガー」を参照してください。

    図12-3 エンティティ・レベルのメソッド・バリデータの追加

    「検証ルールの追加」ダイアログの図

    Methodエンティティ・バリデータの場合は、「検証実行」タブを使用して検証レベルを指定することもできます。「トランザクション・レベルの遅延実行」を選択した場合は、エンティティがコミットされるとバリデータが起動します。これは、1つの表に編集対象の複数の行が表示される場合に役立ちます。

  6. 「失敗処理」タブをクリックして、検証規則が失敗した場合にユーザーに対して表示されるエラー・メッセージを入力または選択します。

    詳細は、11.7項「検証エラー・メッセージの作成」を参照してください。

12.2.4 エンティティ・レベルのメソッド・バリデータを作成するときに行われる処理

メソッド・バリデータを新たに追加すると、JDeveloperでは新しい検証ルールを反映するように、XMLドキュメントが更新されます。メソッドの作成を指定した場合、そのメソッドはエンティティ・オブジェクトのカスタムJavaクラスに追加されます。例12-3は、注文のDateShippedDateOrderedより後の日付であることを確認する、簡単なエンティティ・レベル検証ルールを示しています。

例12-3 簡単なエンティティ・レベルのメソッド・バリデータ

public boolean validateDateShippedAfterDateOrdered() {
  Date DateShipped = getDateShipped();
  Date DateOrdered  = getDateOrdered();
  if (DateShipped != null && DateShipped.compareTo(DateOrdered) < 0) {
    return false;
  }
  return true;
}

「検証ルールの追加」ダイアログの「検証実行」タブで「トランザクション・レベルの遅延実行」を選択し、エンティティ・オブジェクトを表示するページでSkipValidation="skipDataControls"と設定した場合は、トランザクションの時間まで検証を延期できます。これにより、1つの表で複数の行を変更してから、ユーザーのコミット時にそれらをグループとして検証できます。例12-4は、エンティティ行の集合の部門名がNULLでないことを検証するメソッド・バリデータを示しています。

例12-4 簡単なトランザクション・レベルのメソッド・バリデータ

// Validation method for Departments.
public boolean validateDepartments(ArrayList ctxList) {
   Iterator iter = ctxList.iterator();
   while (iter.hasNext()) {
      JboValidatorContext entValContext = (JboValidatorContext)iter.next();
      DepartmentsImpl deptEO = (DepartmentsImpl)entValContext.getSource();
      if (deptEO.getDepartmentName() == null) {
         // if Dept is null, throw error
         return false;
      }
   }
   return true;
}

12.2.5 検証規則エラー・メッセージの翻訳に関する必知事項

エンティティ・オブジェクト属性のロケール固有のUIコントロールのヒントと同様に、検証規則のエラー・メッセージは、エンティティ・オブジェクトのコンポーネント・メッセージ・バンドル・ファイルに追加されます。メッセージ・バンドル内のこれらのエンティティは、アプリケーションのデフォルトのロケールの文字列を表します。検証エラー・メッセージの翻訳バージョンについては、4.7項「リソース・バンドルの使用」で説明したUIコントロール・ヒントの翻訳と同様の手順で追加してください。

12.3 プログラム的な導出属性値の割当て

宣言的なデフォルト設定では不十分なとき、次の場合にエンティティ・オブジェクトでプログラムによるデフォルト設定を実行できます。

12.3.1 新しい行に対する作成時のデフォルト値の指定方法

create()メソッドは、エンティティ行の最初の作成時にデフォルト値の初期化処理を可能にするエンティティ・オブジェクト・イベントを提供します。例12-5は、エンティティ・オブジェクトの作成メソッドのオーバーライドを示しています。このメソッドは、新しい注文エンティティ行に、DateOrdered属性を移入する属性のsetterメソッドをコールします。

デフォルト値は、Groovy式を使用して定義することもできます。詳細は、4.10.6項「静的なデフォルト値を定義する方法」を参照してください。

例12-5 新しい行の属性値に対する、プログラムによるデフォルト設定

// In entity object implementation class 
protected void create(AttributeList nameValuePair) {
   super.create(nameValuePair);
   this.setDateOrdered(new Date());
}

注意:

オーバーライドされたcreate()メソッド内でsetAttribute()メソッドをコールした場合、新規行はユーザー変更の行としてマークされません。このようにプログラム的に割り当てられたデフォルト値は、宣言的に割り当てられたデフォルト値のように動作します。また、create()メソッドに加えた変更はすべてsuper.create()のコール後に実行される点にも注意してください。


12.3.1.1 create()メソッドとinitDefaultExpressionAttributes()メソッドのいずれかの選択

行が最初に作成されたとき、および初期化状態にリフレッシュされたときの両方で実行するプログラム的なデフォルト設定ロジックでは、initDefaultExpressionAttributes()メソッドをオーバーライドする必要があります。

エンティティ行がNew状態であり、そのエンティティ行に対してrefresh()メソッドをコールした場合、REFRESH_REMOVE_NEW_ROWSフラグまたはREFRESH_FORGET_NEW_ROWSフラグを指定しないと、そのエンティティ行はInitialized状態に戻ります。このプロセスの一環として、エンティティ・オブジェクトのinitDefaultExpressionAttributes()メソッドが実行されますが、create()メソッドは再度実行されません。

12.3.1.2 データベース順序からの属性値のデフォルト設定

4.10.9項「トリガーが割り当てられた値との同期方法」で、主キーの属性にDBSequence型を使用する方法を説明しています。この種の属性の値は、コミット時にデータベース・シーケンスによって取り込む必要があります。エンティティ行の作成時にユーザーが値を参照でき、この値がデータ保存時に変更されないように、順序番号を事前に割り当てる必要が生じることがあります。そのためには、例12-6に示すように、オーバーライドされたcreate()メソッドでoracle.jbo.serverパッケージのSequenceImplヘルパー・クラスを使用します。これは、エンティティ・オブジェクトのカスタムJavaクラスからのコードを示しています。super.create()をコールした後に、順序名と現在のトランザクション・オブジェクトを渡し、SequenceImplオブジェクトの新規インスタンスを作成します。続いてSequenceImplgetSequenceNumber()メソッドからの戻り値を含むsetWarehouseId()属性のsetterメソッドをコールします。


注意:

このアプローチに対するメタデータ駆動型の代替の詳細は、4.14.5項「Oracle順序を使用した主キー値の割当て」を参照してください。


例12-6 作成時に順序からの属性値のデフォルト設定

// In entity object implementation class 
import oracle.jbo.server.SequenceImpl;
// Default WarehouseId value from WAREHOUSE_SEQ sequence at entity row create time
protected void create(AttributeList attributeList) {
    super.create(attributeList);
    SequenceImpl sequence = new SequenceImpl("WAREHOUSE_SEQ",getDBTransaction());
    setWarehouseId(sequence.getSequenceNumber());
}

12.3.2 保存前の導出値の割当て方法

行を保存する前に、プログラムによるデフォルト値をエンティティ・オブジェクトの属性値に割り当てる場合は、prepareForDML()メソッドをオーバーライドし、適切な属性のsetterメソッドをコールして、導出された属性値を移入します。INSERTUPDATEまたはDELETEの処理中にのみ割当てを実行するには、DML_INSERTDML_UPDATEDML_DELETEのそれぞれの整数値の定数と、このメソッドに渡されたoperationパラメータの値を比較できます。

例12-7は、導出値を割り当てるオーバーライドされたprepareForDML()メソッドを示しています。

例12-7 PrepareForDMLを使用した保存前の導出値の割当て

protected void prepareForDML(int operation, TransactionEvent e) {
  super.prepareForDML(operation, e);
  //Populate GL Date
  if (operation == DML_INSERT) {
    if (this.getGlDate() == null) {
      String glDateDefaultOption = 
        (String)this.getInvoiceOption().getAttribute("DefaultGlDateBasis");
      if ("I".equals(glDateDefaultOption)) {
        setAttribute(GLDATE, this.getInvoiceDate());
      } else {
        setAttribute(GLDATE, this.getCurrentDBDate());
      }
    }
  }
 
  //Populate Exchange Rate and Base Amount if null
  if ((operation == DML_INSERT) || (operation == DML_UPDATE)) {
    BigDecimal defaultExchangeRate = new BigDecimal(1.5);
    if ("Y".equals(this.getInvoiceOption().getAttribute("UseForeignCurTrx"))) {
      if (!(this.getInvoiceCurrencyCode().equals(
                            this.getLedger().getAttribute("CurrencyCode")))) {
        if (this.getExchangeDate() == null) {
          setAttribute(EXCHANGEDATE, this.getInvoiceDate());
        }
        if (this.getExchangeRateType() == null) {
          String defaultConvRateType = 
            (String)this.getInvoiceOption().getAttribute("DefaultConvRateType");
          if (defaultConvRateType != null) {
            setAttribute(EXCHANGERATETYPE, defaultConvRateType);
          } else {
            setAttribute(EXCHANGERATETYPE, "User");
          }
        }
        if (this.getExchangeRate() == null) {
          setAttribute(EXCHANGERATE, defaultExchangeRate);
        }
        if ((this.getExchangeRate() != null) && 
            (this.getInvoiceAmount() != null)) {
          setAttribute(INVAMOUNTFUNCCURR, 
                     (this.getExchangeRate().multiply(this.getInvoiceAmount())));
        }
      } else {
        setAttribute(EXCHANGEDATE, null);
        setAttribute(EXCHANGERATETYPE, null);
        setAttribute(EXCHANGERATE, null);
        setAttribute(INVAMOUNTFUNCCURR, null);
      }
    }
  }
}

12.3.3 属性値が設定されている場合の、導出値の割当て方法

他の属性値が設定されているときに、導出された属性値を割り当てるには、最後の属性のsetterメソッドにコードを追加します。例12-8は、エンティティ・オブジェクトのAssignedTo属性に対するsetterメソッドを示しています。

例12-8 AssignedTo属性の変更に応じて割当て日を設定するメソッド

public void setAssignedTo(Number value) {
  setAttributeInternal(ASSIGNEDTO, value);
  setAssignedDate(getCurrentDateWithTime());
}

setAttributeInternal()をコールしてAssignedTo属性の値を設定すると、AssignedDate属性のsetterメソッドにより、現在日時の値が設定されます。


注意:

ここで説明した生成済の属性のgetterメソッドとsetterメソッドへのカスタム・コードの追加は、安全に行うことができます。JDeveloperでクラスのコードが変更された場合でも、カスタム・コードはそのまま保持されます。


12.4 refreshメソッドを使用した、エンティティに対する保留中の変更の取消し

refresh(int flag)メソッドを行に対して使用すると、保留中のすべての変更をリフレッシュできます。refresh()メソッドの動作は、パラメータとして渡すフラグによって決まります。この動作を制御する3つの主要なフラグの値は、Rowインタフェースの次の定数です。

12.4.1 リフレッシュ中の新規行の動作の制御方法

デフォルトでは、refresh()を実行したNew状態のすべてのエンティティ行がInitialized状態の空白行に戻ります。宣言的なデフォルト値と、initDefaultExpressionAttributes()メソッドに記述されたプログラム的なデフォルトはリセットされますが、エンティティ・オブジェクトのcreate()メソッドは、この無効化のプロセスでは実行されません。

このデフォルトの動作は、次の2つのフラグのうちの1つと、12.4項のフラグの1つをビット単位のOR演算子によって組み合せて変更できます。

  • REFRESH_REMOVE_NEW_ROWS: リフレッシュ時に新しい行が削除されます。

  • REFRESH_FORGET_NEW_ROWS: 新しい行はDeadとマークされます。

12.4.2 構成される側の子エンティティ行へのリフレッシュのカスケード方法

REFRESH_CONTAINEESフラグと、12.4項および12.4.1項で説明した有効なフラグの組合せをビット単位のOR演算子を使用して、構成される側の子エンティティ行をrefresh()操作でカスケードできます。このため、エンティティにより、構成される側の子エンティティに対し、同じモードでrefresh()が実行されます。

12.5 検証でのビュー・オブジェクトの使用

ビジネス・ロジックでSQL問合せの実行が必要とされる場合、一般的には、そのタスクの実行にはビュー・オブジェクトを使用します。検証のために実行するSQL文では、エンティティ・ベースのビュー・オブジェクトであれば、エンティティ・キャッシュ内の保留中の変更が参照されます。読取り専用ビュー・オブジェクトでは、データベースに送信されたデータのみを取得します。

12.5.1 ビュー・オブジェクトに対する検証用ビュー・アクセッサの使用方法

エンティティ・オブジェクトは任意のアプリケーション・シナリオで再利用されるので、特定のアプリケーション・モジュールのデータ・モデル内のビュー・オブジェクト・インスタンスに直接依存してはなりません。依存する場合、他のアプリケーション・モジュールで再使用ができないという事態が発生します。

かわりに、ビュー・アクセッサを使用して、ビュー・オブジェクトに対して検証する必要があります。詳細は、14.4.1項「エンティティ・オブジェクトまたはビュー・オブジェクトのビュー・アクセッサの作成方法」を参照してください。

例12-9に示すように、検証コードはビュー・アクセッサを使用してビュー・オブジェクトにアクセスし、バインド変数を設定します。

例12-9 メソッド・バリデータでの検証ビュー・オブジェクトの使用

// Sample entity-level validation method
public boolean validateSomethingUsingViewAccessor() { 
  RowSet rs = getMyValidationVO();
  rs.setNamedBindParameter("Name1", value1); 
  rs.setNamedBindParameter("Name2", value2); 
  rs.executeQuery(); 
  if ( /* some condition */) { 
  /* 
   * code here returns true if the validation succeeds 
   */ 
  } 
  return false; 
} 

ベスト・プラクティス:

プログラミングで行セットにアクセスする際は、必ず行セットのセカンダリ・イテレータの作成を検討してください。これにより、ビュー・オブジェクトをユーザー・インタフェース・プロジェクトのデータ・コントロールとして表示する場合に使用される、デフォルト行セットイテレータの現在の行セットに混乱が生じないようにします。作業中の行セットに対してcreateRowSetIterator()をコールし、セカンダリとして指定する行セット・イテレータを作成します。プログラミングによる反復を修了すると、コードは行セットに対してcloseRowSetIterator()をコールし、セカンダリ・イテレータをメモリーから削除する必要があります。


サンプル・コードで示すように、検証に使用されるビュー・オブジェクトには通常、1つ以上の名前付きのバインド変数が含まれます。この例では、setNamedBindParameter()メソッドを使用してバインド変数を設定します。ただし、ビュー・アクセッサ定義用ページでGroovy式を使用して、JDeveloperで変数を宣言して設定することもできます。

ビュー・オブジェクトが取得するデータの種類によって、この例の「/* some condition */」式は異なります。たとえば、ビュー・オブジェクトのSQL問合せがCOUNT()などの集約関数を選択した場合、条件では一般的にrs.first()メソッドを使用して最初の行にアクセスし、続いてgetAttribute()メソッドを使用して属性値にアクセスし、そのカウントに対してデータベースが戻す結果を参照します。

問合せから0行または1行のどちらが戻されたかによって、検証が成功または失敗した場合、この条件はrs.first()nullを戻したかどうかのみを検証します。rs.first()nullを戻した場合、最初の行は存在しません。つまり、問合せで行は検出されていません。また、ビュー・オブジェクトから取得された1つ以上の問合せ結果に対し、検証の成否を繰り返し確認することもあります。

12.5.2 指定された型のすべてのエンティティに関連する条件の検証方法

データベースに変更がポストされた後、コミットされる前に、変更保留中のリストのエンティティに対して、beforeCommit()メソッドがコールされます。これは、特定の型のすべてのエンティティ行に対して規則を適用する必要のある、ビュー・オブジェクト・ベースの検証を実行する場合に役立つメソッドです。


注意:

トランザクション・レベルのバリデータを使用して宣言的に検証を実行することもできます(11.6.4項「トランザクション・レベルの検証の設定方法」を参照)。


beforeCommit()ロジックで例外ValidationExceptionがスローされた場合、構成中にjbo.txn.handleafterpostexcプロパティをtrueに設定する必要があります。これにより、フレームワークは現在のコミット・サイクルにおいて、データベースに送信済(かつコミット前)の他のエンティティ・オブジェクトのメモリー内の状態のロールバックを自動的に処理します。

たとえば、例12-10に示す、オーバーライドされたbeforeCommit()について考えます。この例では、多相エンティティ・オブジェクトに基づいた3つのビュー・オブジェクト(PersonsStaffおよびSupplier)があり、それらが多相化識別子としてPersonTypeCode属性を持っています。PersonsImpl.javaファイルには、検証メソッドをコールするようにオーバーライドされたbeforeCommit()メソッドがあります。この検証メソッドでは、各ユーザー・タイプを通じてプリンシパル名が一意になっていることを確認するための4番目のビュー・オブジェクト、PersonsValidatorが使用されています。たとえば、Staffビュー・オブジェクトのPrincipalNameとしてSKINGが存在する場合、このユーザー・タイプまたは他のユーザー・タイプに別のSKINGにできません。

例12-10 特定タイプのすべてのエンティティを検証するためのbeforeCommit()のオーバーライド

// In entity object implementation class 
. . . 
@Override
public void beforeCommit(TransactionEvent transactionEvent) throws ValidationException {
  String principalName = getPrincipalName();
  if (!validatePrincipalNameIsUniqueUsingViewAccessor(principalName)) {
    throw new ValidationException("Principal Name must be unique across person types");
  }
    super.beforeCommit(transactionEvent);
}

public boolean validatePrincipalNameIsUniqueUsingViewAccessor(String principalName) {
RowSet rs = getPersonsValidatorVO();
rs.setNamedWhereClauseParam("principalName", principalName);
rs.setRangeSize(-1);
rs.executeQuery();
Row[] validatorRows = rs.getAllRowsInRange();
if (validatorRows.length > 1)
  // more than one row has the same princpalName
{
    return false;
}
rs.closeRowSetIterator();
return true;
}

12.5.3 ビュー・アクセッサによる行セットのアクセスに関する必知事項

エンティティ・オブジェクトまたはビュー・オブジェクトのビジネス・ロジックが独自のビュー・アクセッサ行セット上で反復処理を行い、そのビュー・アクセッサがモデルによって定義された値のリストでも使用されていない場合、セカンダリ行セット・イテレータを使用する必要はありません。たとえば、ある名前のバインド・パラメータを取るビュー・オブジェクトのAirportValidationVAという名前のビュー・アクセッサがエンティティ・オブジェクトにある場合、GroovyスクリプトまたはJavaを使用して独自のアクセッサ行セットでの反復処理を行うことができます。例12-11に、ビュー・アクセッサ行セット上で反復処理を行うGroovyスクリプトを示します。

例12-11 Groovyスクリプトでのビュー・アクセッサの使用

AirportValidationVA.setNamedWhereClauseParam("VarTla",newValue)
AirportValidationVA.executeQuery();
return AirportValidationVA.first() != null;

例12-12に、ビュー・アクセッサ行セット上で反復処理を行うJavaメソッド・バリデータを示します。

例12-12 メソッド・バリデータでのビュー・アクセッサの使用

public boolean validateJob(String job) {
   getAirportValidationVA().setNamedWhereClauseParam("VarTla",job);
   getAirportValidationVA().executeQuery();
   return getAirportValidationVA().first() != null;
}

12.6 アソシエーション・アクセッサを使用した、関連するエンティティ行へのアクセス

関連するエンティティ・オブジェクトから情報にアクセスするには、エンティティ・オブジェクトのカスタムJavaクラスにあるアソシエーション・アクセッサ・メソッドを使用します。アクセッサ・メソッドをコールすると、アソシエーションのカーディナリティに応じて、すべての関連するエンティティ行、またはエンティティ行のセットに簡単にアクセスできます。

12.6.1 関連するエンティティ行へのアクセス方法

アクセッサを使用して関連するエンティティ行にアクセスできます。例12-13は、EmpEOエンティティ・オブジェクトのカスタムJavaクラス内のpostChanges()メソッドのオーバーライドを示す、SummitADFアプリケーション・ワークスペース内のcontrolpostorderモジュールからのコードを示しています。getDeptEO()アソシエーション・アクセッサを使用して、従業員の関連部門を取得しています。

例12-13 Createメソッドにおける親エンティティ行へのアクセス

// In EmpEOImpl.java
public void postChanges(TransactionEvent transactionEvent) {
   /* If current entity is new or modified */
   if (getPostState() == STATUS_NEW || 
      getPostState() == STATUS_MODIFIED) {
      /* Get the associated dept for the employee */
      DeptEOImpl dept = getDeptEO();
      /* If there is an associated dept */
      if (dept != null) {
         /* And if it's post-status is NEW */
         if (dept.getPostState() == STATUS_NEW) {
            /*
   * Post the department first, before posting this
   * entity by calling super below
   */
            dept.postChanges(transactionEvent);
         }
      }
   }
   super.postChanges(transactionEvent);
}

12.6.2 関連するエンティティ行セットへのアクセス方法

アソシエーションのカーディナリティが、複数の行が戻されるようになっている場合、アソシエーション・アクセッサを使用してエンティティ行のセットを戻すことができます。

例12-14は、DeptEOエンティティ・オブジェクトのカスタムJavaクラスのオーバーライドされたpostChanges()メソッドのコードを示しています。setDeptId()アソシエーション・アクセッサを使用して各行のDeptId属性を更新するために、getEmpEO()アソシエーション・アクセッサを使用してEmpEO行のRowSetオブジェクトを取得する方法を示しています。

例12-14 アソシエーション・アクセッサを使用した関連するエンティティ行セットへのアクセス

// In DeptEOImpl.java in the controlpostorder module 
// of the SummitADF application workspace
RowSet newEmployeesBeforePost = null;
@Override
public void postChanges(TransactionEvent transactionEvent) {
      /* Update references only if Department is a NEW one */
   if (getPostState() == STATUS_NEW) {
      /*
      * Get a rowset of employees related
      * to this new department before calling super
      */
   newEmployeesBeforePost = (RowSet)getEmpEO();
   }
   super.postChanges(transactionEvent);
    }
@Override
protected void refreshFKInNewContainees() {
   if (newEmployeesBeforePost != null) {
      Number newDeptId = getId().getSequenceNumber();
         /* 
         * Process the rowset of employees that referenced
         * the new department prior to posting, and update their
         * Id attribute to reflect the refreshed Id value
         * that was assigned by a database sequence during posting.
         */
      while (newEmployeesBeforePost.hasNext()){
         EmpEOImpl emp = (EmpEOImpl)newEmployeesBeforePost.next();
         emp.setDeptId(newDeptId);
      }
      closeNewProductRowSet();
   }  
}

12.7 認証されたユーザーに関する情報の参照

アプリケーションで「ADFセキュリティの構成」ウィザードを実行して、ADF認証サーブレットによるユーザーのログインとログアウトのサポートを有効にした場合、oracle.jbo.server.SessionImplオブジェクトでは、認証されたユーザーの名前と、そのユーザーの属するロールを取得するメソッドを使用できます。これは、クライアントがアクセス可能なoracle.jbo.Sessionインタフェースの実装クラスです。

認証済ユーザーに関する情報へのアクセス方法の詳細は、41.11.3.3項「現在のユーザー名、テナント名またはテナントIDの特定方法」および41.11.3.4項「Java EEセキュリティ・ロールのメンバーシップ特定方法」を参照してください。

Oracle Fusion Webアプリケーションのセキュリティ機能の詳細は、第41章「Fusion WebアプリケーションでのADFセキュリティの有効化」を参照してください。

12.8 元の属性値へのアクセス

エンティティ属性値が現在のトランザクション内で変更されている場合、属性getterメソッドをその属性値に対してコールすると、この保留中の変更値が戻されます。変更前の元の値を取得する場合があります。getPostedAttribute()メソッドを使用すると、エンティティ・オブジェクトのビジネス・ロジックで、エンティティ行が変更される前にデータベースから読み取った、属性の元の値を確認できます。このメソッドは属性indexを引数として取るので、JDeveloperに保管されている正しく生成された属性インデックス列挙を渡します。

12.9 現在のユーザー・セッションに関する情報の格納

現在のユーザー・セッションに関連した情報を、エンティティ・オブジェクトのビジネス・ロジックにより参照可能な方法で格納する必要がある場合、Sessionオブジェクトで提供されるユーザー・データのハッシュ表を使用できます。

12.9.1 現在のユーザー・セッションに関する情報の格納方法

新規ユーザーがアプリケーション・モジュールに初めてアクセスする場合、prepareSession()メソッドがコールされます。例12-15に示すように、アプリケーション・モジュールはprepareSession()をオーバーライドし、ビュー・オブジェクト・インスタンスのretrieveUserInfoForAuthenticatedUser()メソッドをコールして、認証されたユーザーに関する情報を取得します。次に、ユーザーの数値IDをユーザー・データ・ハッシュ表に保存するため、setUserIdIntoUserDataHashtable()ヘルパー・メソッドをコールします。

例12-15 ユーザー情報の動問合せのためのprepareSession()のオーバーライド

// In the application module
protected void prepareSession(Session session) {
  super.prepareSession(session);
  /*
   * Query the correct row in the VO based on the currently logged-in
   * user, using a custom method on the view object component
   */
  getLoggedInUser().retrieveUserInfoForAuthenticatedUser();     
  setUserIdIntoUserDataHashtable();
}

例12-16に、ビュー・オブジェクトのretrieveUserInfoForAuthenticatedUser()メソッドのコードを示します。これは、それ自体のEmailAddressバインド変数を、セッションの認証されたユーザー名に設定し、executeQuery()をコールしてUSERS表から追加のユーザー情報を取得します。

例12-16 ユーザー詳細の追加取得のための、認証されたユーザー名へのアクセス

// In the view object's custom Java class
public void retrieveUserInfoForAuthenticatedUser() {
  SessionImpl session = (SessionImpl)getDBTransaction().getSession();
  setEmailAddress(session.getUserPrincipalName());
  executeQuery();
  first();
}

ビュー・オブジェクトが取得する、認証されたユーザーの情報の1つには、メソッドの結果として戻されるユーザーの数値ID番号があります。たとえば、ユーザーskingには、数値のUserIdとして300が割り当てられています。

例12-17は、例12-15prepareSession()コードで使用される、setUserIdIntoUserDataHashtable()ヘルパー・メソッドを示しています。このメソッドでは、文字列定数CURRENT_USER_IDで指定されるキーを使用して、数値ユーザーIDをユーザー・データ・ハッシュ表に格納します。

例12-17 エンティティ・オブジェクトからのアクセスのためのユーザー・データ・ハッシュ表への情報の設定

// In the application module
private void setUserIdIntoUserDataHashtable() {
  Integer userid = getUserIdForLoggedInUser();
  Hashtable userdata = getDBTransaction().getSession().getUserData();
  userdata.put(CURRENT_USER_ID, userid);
}  

この例の対応するエンティティ・オブジェクトでは、例12-18のようなヘルパー・メソッドを使用して、この数値ユーザーIDを参照するようにcreate()メソッドをオーバーライドできます。オーバーライドされたメソッドでは、CreatedBy属性を現在認証されているユーザーの数値ユーザーIDにプログラム的に設定します。

例12-18 ヘルパー・メソッドでの現在のユーザーIDの参照

protected Number getCurrentUserId() {
  Hashtable userdata = getDBTransaction().getSession().getUserData();
  Integer userId = (Integer)userdata.get(CURRENT_USER_ID);
  return userdata != null ? Utils.intToNumber(userId):null;
}

12.9.2 現在のユーザー・セッション情報へのアクセスにGroovyを使用する方法

フレームワークでGroovyスクリプトを使用できる、オブジェクトにアクセス可能なadfという名前のトップレベルのオブジェクトが用意されています。adf.userSessionオブジェクトは、ADFビジネス・コンポーネント・ユーザー・セッションへの参照を返します。これを使用してセッションに含まれているuserDataハッシュ・マップ内の値を参照できます。

例12-19に、MyKeyという名前のuserDataハッシュ・マップ・キーの参照に使用するGroovyスクリプトを示します。

例12-19 Groovyスクリプトでの現在のユーザー・セッションへのアクセス

adf.userSession.userData.MyKey

12.10 現在の日時へのアクセス

エンティティ・オブジェクトのビジネス・ロジックにおいては、現在の日時の参照が役立つ場合があります。次のGroovyスクリプト式を使用すると、現在の日付または現在の日付と時間を参照できます。

エンティティ・オブジェクトのビジネス・ロジックでのGroovyスクリプトの使用方法の詳細は、3.5.6項「ビジネス・コンポーネントでのGroovyスクリプト言語の使用方法」を参照してください。

12.11 正常に完了したコミットに関する通知の送信

変更保留中のリストに含まれていたエンティティ行に対してafterCommit()メソッドがコールされ、データベースに正しく格納されます。このメソッドを使用して、コミットに関する通知を送信できます。

コミット成功時に通知を送信するもっとよい方法は、ビジネス・イベントを宣言する方法です。ビジネス・イベントの作成方法の詳細は、4.12項「ビジネス・イベントの作成」を参照してください。

12.12 エンティティ行削除の条件付き禁止

remove()メソッドは、エンティティ行削除の前に、その行に対して起動します。remove()メソッドでは、JboExceptionをスローし、該当する条件を満たさない場合は行の削除を回避するよう設定できます。

たとえばremove()メソッド内で、エンティティ・オブジェクトの状態を判断するテストを追加し、それが新規レコードの場合にのみ削除可能にすることができます。例12-20に、この方法を示します。

例12-20 remove()メソッドのオーバーライドによる削除前のエンティティ状態の確認

// In entity object custom Java class
private boolean isDeleteAllowed() {
    byte s = this.getEntityState();
  return s==STATUS_NEW;
}
 
/**
 * Add entity remove logic in this method.
 */
public void remove() {
  if (isDeleteAllowed())
    super.remove();
  else
      throw new JboException("Delete not allowed in this view");
}

注意:

このエンティティ・オブジェクトでは、既存の構成される側の子行がある場合、マスター・エンティティ行の削除が宣言的に回避されます。このオプションは、アソシエーションの概要エディタの「関連」ページで設定します。


12.13 属性に対する条件付きの更新可能性の判断

エンティティ・オブジェクト・クラス内のisAttributeUpdateable()メソッドをオーバーライドすると、特定の属性が更新可能かどうかを、実行時に適切な条件に従ってプログラム的に判断できます。

例12-21は、現在の認証されたユーザーがスタッフ・メンバーである場合にのみPersonTypeCode属性を更新可能にするため、エンティティ・オブジェクトによりisAttributeUpdateable()がどのようにオーバーライドされるかを示しています。エンティティ・オブジェクトでは、このメソッドを実行する際、更新可能性の確認対象となる整数属性索引を渡します。

特定の属性に対する条件付きの更新可能性ロジックは、属性索引に基づいて、if文またはswitch文内に実装できます。ここでは、PERSONTYPECODEがエンティティ・オブジェクトのカスタムJavaクラスに保持されている整数属性の索引列挙を参照します。

例12-21 属性の更新可能性の実行時の条件付きの判断

// In the entity object custom Java class
public boolean isAttributeUpdateable(int index) {
  if (index == PERSONTYPECODE) {
    if (!currentUserIsStaffMember()) {
      return super.isAttributeUpdateable(index);
    }
    return CUSTOMER_TYPE.equals(getPersonTypeCode()) ? false : true;
  }
  return super.isAttributeUpdateable(index);
}

注意:

エンティティ・ベースのビュー・オブジェクトは、エンティティ・オブジェクト内でカプセル化された他の要素と同様に、この条件付きの更新可能性も継承します。この種の条件付き更新可能性ロジックを、一時ビュー・オブジェクト属性に固有の方法で実装する必要がある場合、または、ビュー・オブジェクト内の複数のエンティティ・オブジェクトのデータを含む一部の条件を適用する場合、ビュー・オブジェクトのビュー行クラス内の同じメソッドをオーバーライドすると、目的の結果が得られます。


12.14 カスタム検証規則の実装

ADFビジネス・コンポーネントには、開発者が使用できる組込みの宣言的検証規則の基本セットが付属しています。ただし、エンティティ・オブジェクト用のバリデータ・アーキテクチャの強力な機能は、独自のカスタム検証規則を作成できることです。同じ種類の検証コードを繰り返し作成している場合は、カスタム検証規則クラスを作成し、このような共通の検証パターンをパラメータ化された方法で取得できます。

定義したカスタム検証規則クラスは、JDeveloperに登録し、組込み規則と同じように簡単に使用できます。実際、カスタム検証規則をカスタムUIパネルにバンドルすることもできます。JDeveloperはこれを利用して、検証規則で必要とするパラメータを開発者が簡単に使用および構成できるようにします。

12.14.1 カスタム検証規則の作成方法

エンティティ・オブジェクト用のカスタム検証規則を作成するには、oracle.jbo.rulesパッケージのJboValidatorInterfaceを実装するJavaクラスが必要です。「新規ギャラリ」からスケルトン・クラスを作成できます。

始める前に:

カスタム検証規則に関する知識があると役立つ場合があります。詳細は、12.14項「カスタム検証規則の実装」を参照してください。

また、他の検証機能を使用して追加できる機能についても理解しておくと役立ちます。詳細は、12.1.2項「プログラム的なビジネス・ルールの追加機能」を参照してください。

カスタム・バリデータを作成するには:

  1. 「アプリケーション」ウィンドウで、バリデータを作成するプロジェクトを右クリックし、「新規」→「ギャラリから」を選択します。

  2. 「新規ギャラリ」で、「ビジネス層」を開き、「ADFビジネス・コンポーネント」を選択してから、「検証ルール」を選択し、「OK」をクリックします。

  3. 「検証ルール・クラスの作成」ダイアログで、ルールの名前とパッケージを入力します。

  4. 表示名と説明を入力して、「OK」をクリックします。

例12-22に示すように、JBOValidatorInterfaceには、1つのメインvalidate()メソッドと、Descriptionプロパティ用のgetterおよびsetterメソッドが含まれます。

例12-22 すべての検証規則が実装する必要のあるJboValidatorInterface

package oracle.jbo.rules;
public interface JboValidatorInterface {
  void validate(JboValidatorContext valCtx) { }
  java.lang.String getDescription() { }
  void setDescription(String description) { }
}

検証規則の動作がパラメータ化されて柔軟性が増してから、検証クラスの各パラメータにBeanプロパティを追加します。たとえば、例12-23のコードにはDateMustComeAfterRuleという名前のカスタム検証規則が含まれており、ある日付属性が別の日付属性より後でなければならないことを検証します。規則を使用する開発者が検証対象の2つの日付として使用する日付属性の名前を構成できるように、このクラスではinitialDateAttrNamelaterDateAttrNameという2つのプロパティが定義されています。

例12-23は、カスタム検証規則を実装するコードを示しています。これは、AbstractValidatorを拡張し、エンティティ・オブジェクトのカスタム・メッセージ・バンドルの使用を継承しています。開発者がエンティティ・オブジェクトの規則を使用すると、JDeveloperは検証エラー・メッセージをここに保存します。

検証規則のvalidate()メソッドは、実行時に規則クラスが機能を実行する必要がある場合に常に呼び出されます。このコードが実行する基本的な手順は次のとおりです。

  1. エンティティ・レベルでバリデータが正しくアタッチされていることを確認します。

  2. 検証するエンティティ行を取得します。

  3. 先の日と後の日の属性の値を取得します。

  4. 先の日が後の日より前であることを検証します。

  5. 検証が失敗した場合は例外をスローします。

例12-23 カスタムのDateMustComeAfterRule

// package and imports omitted
public class DateMustComeAfterRule extends AbstractValidator
       implements JboValidatorInterface {
  /**
   * This method is invoked by the framework when the validator should do its job
   */
  public void validate(JboValidatorContext valCtx) {
    // 1. If validator is correctly attached at the entity level...
    if (validatorAttachedAtEntityLevel(valCtx)) {
      // 2. Get the entity row being validated
      EntityImpl eo = (EntityImpl)valCtx.getSource();
      // 3. Get the values of the initial and later date attributes
      Date initialDate = (Date) eo.getAttribute(getInitialDateAttrName());
      Date laterDate = (Date) eo.getAttribute(getLaterDateAttrName());
      // 4. Validate that initial date is before later date
      if (!validateValue(initialDate,laterDate)) {
        // 5. Throw the validation exception
        RulesBeanUtils.raiseException(getErrorMessageClass(),
                                      getErrorMsgId(),
                                      valCtx.getSource(),
                                      valCtx.getSourceType(),
                                      valCtx.getSourceFullName(),
                                      valCtx.getAttributeDef(),
                                      valCtx.getNewValue(),
                                      null, null);
      }
    }
    else {
      throw new RuntimeException("Rule must be at entity level");
    }
  }
  /**
   * Validate that the initialDate comes before the laterDate.
   */
  private boolean validateValue(Date initialDate, Date laterDate) {
    return (initialDate == null) || (laterDate == null) ||
    (initialDate.compareTo(laterDate) < 0);
  }
  /**
   * Return true if validator is attached to entity object
   * level at runtime.
   */
  private boolean validatorAttachedAtEntityLevel(JboValidatorContext ctx) {
    return ctx.getOldValue() instanceof EntityImpl;
  }
  // NOTE: Getter and Setter Methods omitted
  private String description;
  private String initialDateAttrName;
  private String laterDateAttrName;
}

カスタム検証規則を簡単に再利用できるように、通常は、規則を利用するアプリケーションでの参照用として規則をJARファイルにパッケージします。

12.14.2 規則用の設計時Beanカスタマイザの追加

検証規則クラスはBeanであるため、標準のJavaBeanカスタマイザ・クラスを実装して、設計時にBeanのプロパティを設定しやすくすることができます。例12-23DateMustComeAfter規則の例では、開発者はinitialDateAttrNamelaterDateAttrNameの2つのプロパティを構成する必要があります。

図12-4は、Swing用のJDeveloperビジュアル・デザイナを使用して作成されたDateMustComeAfterRuleCustomizerを示しており、タイトル付きの境界を持つJPanelに、ドロップダウン・リスト用の2つのJLabelプロンプトと2つのJComboBoxコントロールが含まれています。クラスのコードによって、IDEで現在編集されているエンティティ・オブジェクトのDate値属性の名前がドロップダウン・リストに移入されます。これにより、DateMustComeAfterRule検証をエンティティ・オブジェクトに追加する開発者は、検証の開始日と終了日に使用する日付属性を簡単に選択できます。

図12-4 JDeveloperのSwingビジュアル・デザイナを使用した検証規則カスタマイザの作成

カスタマイズされた検証規則エディタの図

カスタマイザとDateMustComeAfterRule Java Beanを関連付けるには、BeanInfoクラスを作成するときの標準的な手順に従います。例12-24で示されているように、DateMustComeAfterRuleBeanInfoは、カスタマイザ・クラスをDateMustComeAfter Beanクラスと関連付けるBeanDescriptorを返します。

通常は、カスタマイザ・クラスとこのBean情報を、設計時専用の独立したJARファイルにパッケージします。

例12-24 カスタマイザとカスタム検証規則を関連付けるためのBeanInfo

package oracle.summit.model...frameworkExt.rules;
import java.beans.BeanDescriptor;
import java.beans.SimpleBeanInfo;
public class DateMustComeAfterRuleBeanInfo extends SimpleBeanInfo {
  public BeanDescriptor getBeanDescriptor() {
    return new BeanDescriptor(DateMustComeAfterRule.class,
                              DateMustComeAfterRuleCustomizer.class);
  }
}

12.14.3 JDeveloperでのカスタム規則の登録および使用方法

カスタム検証規則は作成後、JDeveloper IDEのプロジェクトまたはアプリケーションレベルに追加できるため、他の開発者がその規則を宣言的に使用できます。

12.14.3.1 プロジェクト・レベルでのカスタム・バリデータの登録

カスタム検証規則をプロジェクト・レベルで登録した場合は、プロジェクト内でその検証規則を使用できます。

始める前に:

カスタム検証規則に関する知識があると役立つ場合があります。詳細は、12.14項「カスタム検証規則の実装」を参照してください。

また、他の検証機能を使用して追加できる機能についても理解しておくと役立ちます。詳細は、12.1.2項「プログラム的なビジネス・ルールの追加機能」を参照してください。

カスタム検証規則を登録するには、12.14.1項「カスタム検証規則の作成方法」で説明しているように、先にその検証規則を作成しておく必要があります。

エンティティ・オブジェクトを含むプロジェクトでカスタム検証規則を登録するには:

  1. 「アプリケーション」ウィンドウで、エンティティ・オブジェクトを含むプロジェクトを右クリックし、「プロジェクト・プロパティ」を選択します。

  2. 「プロジェクト・プロパティ」ダイアログで、「ADFビジネス・コンポーネント」を開き、「登録済ルール」を選択します。

  3. 「登録済の規則」ページで、「追加」をクリックします。

  4. 「検証ルールの登録」ダイアログで、作成した検証ルールを参照して検索し、「OK」をクリックします。

12.14.3.2 IDEレベルでのカスタム・バリデータの登録

カスタム検証規則をJDeveloperのIDEレベルで登録すると、現在のプロジェクトのみでなく、他のプロジェクトでもその検証規則を使用できます。

始める前に:

カスタム検証規則に関する知識があると役立つ場合があります。詳細は、12.14項「カスタム検証規則の実装」を参照してください。

また、他の検証機能を使用して追加できる機能についても理解しておくと役立ちます。詳細は、12.1.2項「プログラム的なビジネス・ルールの追加機能」を参照してください。

カスタム検証規則を登録するには、12.14.1項「カスタム検証規則の作成方法」で説明しているように、先にその検証規則を作成しておく必要があります。

IDEレベルのカスタム・バリデータを登録するには:

  1. メイン・メニューから、「ツール」→「プリファレンス」を選択します。

  2. 「プリファレンス」ダイアログで、「ADFビジネス・コンポーネント」を開き、「ルールの登録」を選択します。

  3. 「ルールの登録」ページから、1つ以上の検証規則を追加できます。

    検証ルールを追加するときは、検証ルール・クラスの完全修飾名を指定し、JDeveloperの使用可能なバリデータのリストで表示される検証ルールの名前を設定します。