機械翻訳について

サーバー・スクリプト

アプリケーション・コンポーザは、アプリケーションの拡張に使用するスクリプト言語としてGroovyをサポートしています。 Groovyスクリプトを使用できる様々なコンテキストがあります。

このトピックでは、検証ルール、トリガーおよびオブジェクト関数の使用方法を説明します。これらの関数は、標準オブジェクトまたはカスタム・オブジェクトに対して「サーバー・スクリプト」ノードを使用して定義できます。 アプリケーション・コンポーザを使用したGroovyスクリプトの詳細は、Groovyスクリプト・リファレンス・ガイドを参照してください。

標準またはカスタム・オブジェクトに対して定義できるサーバー・スクリプトには、次のものがあります:

  • 検証ルール

    フィールドまたはオブジェクトのいずれかを検証するスクリプトを記述します。

  • トリガー

    特定のトリガー・イベントが発生するたびにアクションを自動的に実行するトリガー・スクリプトを記述します。

  • オブジェクト関数

    複数のコンテキストで再利用できる関数を記述します。 たとえば、トリガーまたは検証ルール内でオブジェクト関数を再利用できます。

ヒント: サーバー・スクリプトは同期的に実行されるため、スクリプトの実行時間が長い場合やパフォーマンスに負荷がかかる場合にパフォーマンスに影響を与える可能性があります。 このようなロジックを実装する前に、同じロジックを非同期で実行できるかどうかを常に検討してください。 たとえば、かわりにGroovyスクリプト・アクションでオブジェクト・ワークフローを使用できます。

検証ルール

検証ルールは、フィールドまたはオブジェクトに対して定義できる制約です。 フィールドまたはオブジェクトを保存する前に検証する式または長いスクリプトを記述します。 標準またはカスタム・オブジェクトの「サーバー・スクリプト」ノードを使用して検証ルールを定義します。

  • 要件に単一のフィールドが含まれる場合は、フィールドレベルの検証を使用します。

    フィールド・レベルの検証ルールは、標準フィールドまたはカスタム・フィールドで定義できる制約です。 ルールは、対応するフィールドの値が設定され、ユーザーがフィールドからタブ・アウトするたびに、実行時に評価されます。 ルールが実行されると、フィールドの値がまだ割り当てられておらず、ルールが成功した割当までゲート・キーパーとして機能します。 フィールド・レベルで検証ロジックをカバーすると、保存時のGroovy実行のオーバーヘッドが軽減されます。 このオプションは、可能なかぎり使用します。

    ノート: 動的選択リストでは、フィールド・レベルの検証ルールはサポートされません。

    たとえば、「優先度」フィールドを持つカスタムTroubleTicketオブジェクトを考えてみます。 フィールド・レベルの検証ルールを設定して、入力した番号が1から5の間であることを検証できます。

    記述する式(またはそれより長いスクリプト)は、値が有効であるかどうかを示すブール値を返す必要があります。

    • ルールがtrueを返す場合、同じフィールドの他のすべてのフィールド・レベル・ルールもtrueを返すかぎり、フィールド割当は成功します。

    • ルールがfalseを返すと、フィールド割当が発生しなくなります。 また、無効なフィールドはUIで視覚的に強調表示され、構成されたエラー・メッセージがエンド・ユーザーに表示されます。 この状況では割当が失敗するため、フィールドは現在の値を保持します(以前の値がnullだった場合はnullになる可能性があります)。 ただし、webページのUIコンポーネントを使用すると、ユーザーは無効なエントリを表示して修正し、再試行できます。

    Groovyスクリプト・リファレンス・ガイドのフィールド・レベルの検証ルールの定義に関する項を参照してください。

  • オブジェクトの複数の関連フィールド間で検証が必要な場合は、オブジェクトレベルの検証ルールを使用します。 これは、標準オブジェクトまたはカスタム・オブジェクトに対して定義できる制約です。

    オブジェクト・レベルのルールを使用して、オブジェクト内の2つ以上のフィールドに依存する条件を適用します。 これにより、ユーザーが値を割り当てる順序に関係なく、ルールが一貫して適用されます。 ルールは、フレームワークがオブジェクトの検証を試みるたびに評価されます。 この検証は、たとえば、Webフォームで変更を送信するとき、ある行から別の行に移動するとき、およびオブジェクトに対する変更が保存されるときに発生します。 (ユーザーがレコードを変更せずに保存した場合、ルールは評価されません。)

    たとえば、「優先度」および「AssignedTo」フィールドを持つTroubleTicketオブジェクトを考えてみます。後者は、「タイプ」フィールドが「スタッフ・メンバー」である「連絡先」オブジェクトを参照する動的選択リスト・フィールドです。 オブジェクト・レベルの検証ルールを設定して、優先度1または2のトラブル・チケットをスタッフに割り当てないと保存できないことを検証できます。

    記述する式(またはそれより長いスクリプト)は、オブジェクトが有効かどうかを示すブール値を返す必要があります:

    • ルールがtrueを返す場合、同じオブジェクト上の他のすべてのオブジェクト・レベル・ルールがtrueを返すかぎり、オブジェクト検証は成功します。

    • ルールがfalseを返すと、この結果によりオブジェクトが保存されなくなり、構成されたエラー・メッセージがエンド・ユーザーに表示されます。

    Groovyスクリプト・リファレンス・ガイドのオブジェクト・レベルの検証ルールの定義に関する項を参照してください。

ノート: 検証ルールを定義する場合は、次のもの以外のビジネス・ロジックを実装しないでください:

トリガー

トリガーは、標準オブジェクトまたはカスタム・オブジェクトのデフォルト処理ロジックを補完するために記述できるスクリプトです。 特定のイベントが発生すると、トリガーは、トリガー定義で指定したアクションを自動的に実行します。 トリガーは、標準オブジェクトまたはカスタム・オブジェクトの「サーバー・スクリプト」ノードを使用して、オブジェクト・レベルとフィールド・レベルの両方で定義できます。 オブジェクト・トリガーを定義して、レコードの作成、更新、削除などの標準処理ロジックを拡張します。

トリガーを定義するときに、スクリプトを自動的に実行する特定のイベントを選択します。 この特定のイベントはトリガーとも呼ばれます。 Oracleでは、トリガー・スクリプトを定義するときに選択できる、これらのトリガー・イベントのセット番号が用意されています。

トリガーの定義時に正しいトリガー・ポイントを選択します:

  • フィールド・レベルのトリガーは、別のフィールドの値の変更に応じてアクションを実行するために作成するスクリプトです。 フィールド・レベルでトリガーを定義する場合は、「フィールド変更後」トリガーと、このトリガーが監視するフィールドを選択します。 次に、フィールドの値が変更されたときに実行するアクションを定義します。

    「フィールド変更後」トリガーは、指定したフィールドの値が変更されたときに、他の導出フィールド値を計算します。 フィールド・レベルの検証ルールが成功する一方で、他のフィールド・レベルの検証ルールが失敗し、フィールドの値が実際に変更されない可能性があるため、この目的を達成するためにフィールド・レベルの検証ルールを使用しないでください。 通常、フィールド変更導出ロジックは、フィールドの値が変更された場合にのみ実行する必要があるため、「フィールド変更後」トリガーによって、この動作が保証されます。

    Groovyスクリプト・リファレンス・ガイドの「値の変更に対応するためのフィールド・レベルのトリガーの定義」を参照してください。

  • 同様に、オブジェクト・レベルのトリガーは、特定のイベントが発生したときにアクションを実行するスクリプトです。 オブジェクト・レベルのトリガーの場合は、次のような、さらに多くのトリガー・イベントから選択できます:

    • 作成後

      新しいオブジェクト・レコードが作成されたときに起動します。 通常、フィールドのデフォルト値の設定に使用されます。

    • Before Invalidate

      子オブジェクト・レコードのいずれかが作成、更新または削除されると、親オブジェクトに対して起動されます。 関係ロジックで構築します。

    • 削除の前

      オブジェクト・レコードを削除しようとしたときに起動します。 削除を防止する条件を作成するために使用できます。

    • データベースでの挿入の前

      新しいオブジェクトがデータベースに挿入される前に起動します。 依存レコードが存在することを確認したり、重複をチェックするために使用できます。

    • データベースでの更新の前

      既存のオブジェクトがデータベースで変更される前に起動します。 依存レコード値のチェックに使用できます。

    • データベースでの削除の前

      既存のオブジェクトがデータベースから削除される前に起動します。 依存レコード値のチェックに使用できます。

    • データベースでのロールバックの前

    • データベースへの変更のポストの後

      すべての変更がデータベースにポストされた後、永続的にコミットされる前に起動します。 現在のトランザクションの一部として保存される追加の変更を行うために使用できます。

    たとえば、トラブル・チケットが作成されるたびに更新する必要があるOpenTroubleTicketsフィールドを持つContactオブジェクトを考えてみます。 「変更がデータベースにポストされた後」トリガー・イベントを使用して、TroubleTicketオブジェクトにトリガーを作成できます。 イベントが発生すると、トリガーはOpenTroubleTicketsフィールドを新しいカウントで自動的に更新できます。

    選択できるトリガー・イベントの完全なリストは、Groovyスクリプト・リファレンス・ガイドのオブジェクト・レベルのトリガーによるデフォルト処理の補完の定義に関する項を参照してください。

最適なパフォーマンスを得るには、トリガーを使用する際に次のガイドラインに従ってください:

  • オブジェクト当たり10個のトリガーを超えないようにしてください。

  • 単一のトリガー内で論理的に関連するアクションを結合します。 1つのトリガーによって、複数のトリガーよりもパフォーマンスが向上します。

  • トリガーを定義する際は、正しいトリガー・ポイントを選択します。

  • トリガー内で検証ロジックを使用しないでください。 かわりに、検証ロジックに検証ルールを使用します。

  • newView() APIを使用する前に、関連オブジェクトまたは関連コレクション・アクセッサがすでに存在するかどうかを確認します。

    関係がすでに存在する場合は、newView()を使用してオブジェクトを問い合せないでください。 これにより、追加の問合せの起動が回避されます。

  • オブジェクトをプログラムで問い合せる場合は、基礎となる問合せが制限されるように、効率的なビュー基準を選択します。

オブジェクト関数とグローバル関数

再利用可能なコードは、オブジェクト関数またはグローバル関数のいずれかとして記述できます。 複数の異なるコンテキストから同じコードをコールする場合、関数を使用します。 オブジェクト関数は、同じオブジェクト内の任意のスクリプトによってコールすることも、ユーザー・インタフェースのボタンによってトリガーすることもできます。 グローバル関数は、任意のオブジェクトのスクリプトまたは他のグローバル関数から呼び出すことができます。

  • オブジェクト関数は、特定のオブジェクトに固有のビジネス・ロジックをカプセル化するコードに役立ちます。 オブジェクト関数は、同じオブジェクトに関連する他のスクリプトから名前でコールできます。 また、ユーザー・インタフェースのボタンまたはリンクを使用してコールできます。

    サポートされている戻り型とオプションのパラメータ型は、グローバル関数と同じです。 関数の戻り値およびパラメータの最も一般的な型のリストは、Groovyスクリプト・リファレンス・ガイドのグローバル関数でのユーティリティ・コードの定義に関する項を参照してください。

    Groovyスクリプト・リファレンス・ガイドのオブジェクト関数を使用した再利用可能な動作の定義も参照してください。

  • グローバル関数は、複数のオブジェクトで共有するコードに役立ちます。 Groovyスクリプトを使用してユーザー定義関数を記述します。Groovyスクリプトは、アプリケーション・コンポーザ全体ですべてのGroovyスクリプト・エディタで参照できます。 たとえば、2つのグローバル関数を作成して、Groovyスクリプトのブロックの開始をログに記録し、診断メッセージをログに記録する標準ヘルパー・ルーチンを定義できます。

    グローバル関数を呼び出すには、関数名の前にadf.util.プレフィクスを付けます。 ファンクションを定義する場合は、戻り値を指定し、オプションで、コール元が呼び出されたときに渡す必要がある1つ以上の型付きパラメータを指定できます。

    関数の戻り値およびパラメータの最も一般的な型のリストは、Groovyスクリプト・リファレンス・ガイドのグローバル関数でのユーティリティ・コードの定義に関する項を参照してください。

  • 最適なパフォーマンスを得るために、フェッチできるレコードの最大数は500レコードに制限されます。 選択したデータ・サイズによってジョブがExprTimeoutExceptionで失敗する場合は、setMaxFetchSizeを使用してデータ・サイズを減らします。 または、選択的フィルタリングを使用して、ビュー・オブジェクトを介してフェッチされたレコード数を500レコード未満にフィルタします。

特権関数

オブジェクト関数またはグローバル関数のいずれかを定義すると、実行時ユーザーがレコードを作成または更新する権限を持っていないオブジェクトに対して関数が実行される場合があります。 オブジェクトのデータへのアクセス権がないユーザーが、次の2つのことを実行して、完全なアクセス権を持つ関数を実行することを許可します:

  1. 関数の定義中に、「特権」チェック・ボックスを選択して、関数に特権があることを示します。

  2. オブジェクト関数を正常に実行できるように、特権スクリプト管理ロールに適切なレベルのアクセス権があることを確認します。 オブジェクトへのアクセス権は自動的に付与されません。 かわりに、アプリケーション・コンポーザのセキュリティUIを使用してアクセス権を付与する必要があります。

実行時に、ユーザーがUIから特権関数を呼び出すと、特権ロール「特権スクリプト管理」を使用して一時ログイン・セッションがアクティブ化されます。 この特権ロールは、ファンクション内のオブジェクトにアクセスできるため、権限の問題はありません。 一時ログイン・セッションは、単一の関数呼び出しまたは関数が内部的に呼び出すすべての期間のみ持続します。

たとえば、セールス要員は、取引先レコードではなく商談レコードのみにアクセスできます。 営業担当が商談を編集すると、権限のあるGroovyスクリプトを使用して関連アカウントを更新するボタンがあります。 営業担当がアカウント・オブジェクトに対する更新権限を持っていない場合でも、営業担当がボタンをクリックすると、特権ロール・コンテキストに切り替えてアカウント・レコードの更新を完了することで、特権Groovyスクリプトが実行されます。

これを実現するには、アプリケーション・コンポーザのセキュリティUIを使用して、特権ロールである特権スクリプト管理へのアカウント・アクセス権を付与します。