チュートリアル : Worklist アプリケーションの構築

     前  次    新しいウィンドウで目次を開く     
ここから内容

高度なトピック : カスタマイズされたユーザ インタフェースの追加

この章では、Worklist User Portal で使用するためにカスタマイズされたタスク ユーザ インタフェースを作成する方法を説明します。Worklist は、デフォルトのタスク ユーザ インタフェース (ユーザ ポータルの [タスクの作業] ページに表示) を提供します。このユーザ インタフェースは、タスク プランのメタデータに基づいたフォームを動的に作成します。たとえば、デフォルトのタスク ユーザ インタフェースは、タスクの現在のユーザ インタフェースを確認してから、アクションの実行ページでどのアクションを使用できるようにするかを決定します。また、アクションに定義されているプロパティを確認してから、タスク アクションの完了ページにどのプロパティを表示するかを決定します。これにより、ユーザは、カスタム ユーザ インタフェースを開発せずに、Worklist での人間による操作のほとんどを実行できます。

ただし、特定のステップまたはタスク プラン全体のために、インタフェースをカスタマイズし、何を表示するかを制御する必要がある場合があります。Worklist を使用すると、ユーザは、特定のタスク プランに基づいたタスク用 (およびオプションでタスク プランの特定のステップ用) に、カスタマイズされたユーザ インタフェースを実現できます。これにより、カスタム ビジネス ロジック、外部システムなどを、タスク アクションの処理およびプロパティ設定に組み込めます。

カスタム タスク ユーザ インタフェースは、タスク プラン (またはそれらのプランのステップ) に基づいたタスクを表示したときに、Worklist が提供するデフォルトのタスク ユーザ インタフェースの代わりに使用されます。これらは、Worklist User Portal の [タスクの作業] ページに、デフォルトのタスク ユーザ インタフェースの代わりに表示されます。このように、デフォルトのタスク ユーザ インタフェースを細かく置き換えることで、必要な場所のみにカスタム タスク ユーザ インタフェースを指定し、その他の場所ではデフォルトのタスク ユーザ インタフェースを使用できます。

たとえば、融資責任者が、融資を承認または拒否する前に、顧客の信用度を確認する必要がある場合があるとします。カスタム タスク UI を使用すれば、ユーザ ポータルをカスタマイズして、融資責任者が詳細な情報に基づいた決断ができるようにするための情報を表示できます。

この章では、次のトピックについて説明します。

 


Web ページのモデルおよびフローの定義

カスタマイズされたユーザ インタフェースの作成を始める前に、モデルを作成してページの外観を定義します。このチュートリアルでは、管理者審査 (Manager Review) ページおよび資産概要 (Asset Summary) ページ (図 7-1 および図 7-2 を参照) のモデル ページを作成します。

図 7-1 管理者審査モデル ページ

管理者審査モデル ページ

図 7-2 資産概要モデル ページ

資産概要モデル ページ

モデルができました。次の節に従って、ページ フローの定義に進みます。

 


ページ フローの作成

カスタマイズされたユーザ インタフェースのページの外観を決定したら、次のように、これらのページのロジックおよび使用方法を定義します。

  1. [パッケージ・エクスプローラー] ペインで Loan_Web\src フォルダを右クリックし、[新規Arrow symbolその他] を選択します。[ウィザードを選択] ダイアログ ボックスが表示されます。
  2. [Web] の下の [ページ フロー] を選択して、[次へ] をクリックします (図 7-3 を参照)。
  3. 図 7-3 ページ フローの定義


    ページ フローの定義

  4. [新しいページ フロー] ダイアログ ボックスが表示されます。[ページ フロー フォルダ名] フィールドに manager を、また、コントローラ名として ManagerReview を入力します。
  5. [これをネストされたページ フローにする] チェック ボックスをオンにして、[終了] をクリックします (図 7-4 を参照)。
  6. 図 7-4 [新しいページ フロー] ダイアログ ボックス


    [新しいページ フロー] ダイアログ ボックス

    [関連付けられたパースペクティブを開きますか?] ダイアログ ボックスが表示されます。

  7. 表示された [関連付けられたパースペクティブを開きますか?] ダイアログ ボックスで、[常にこの設定を使用する] チェック ボックスをオンにして、[はい] をクリックします。これにより、プロジェクトをページ フロー パースペクティブに関連付けます。
  8. [ページ フロー エディタ] ビューが表示されます (図 7-5 を参照)。
  9. 図 7-5 ページ フロー エディタ


    ページ フロー エディタ

ページ フローを編集する手順は以下のとおりです。

  1. PageFlowControllercom.bea.wli.worklist.TaskUIPageFlowController で置き換えます。
  2. simpleAction = { @Jpf.SimpleAction(name = "begin", path = "index.jsp") }) を削除します。

ページ フローの最初のビューは以下のようになっていました。

@Jpf.Controller(nested = true, simpleActions = { @Jpf.SimpleAction(name = "begin", path = "index.jsp") })

編集後は、以下のようになります。

@Jpf.Controller(nested = true)
public class ManagerReview extends com.bea.wli.worklist.TaskUIPageFlowController {
注意 : この変更によって、「アクション "begin" が見つかりませんでした。」というコンパイル エラーが発生します。このエラーは、次の手順で解決します。コンパイル エラーは、IDE の下部にある [問題] ビューに表示されます。[問題] ビューが開いていることを確認してください。メニューから [問題] ビューを開くには、[ウィンドウArrow symbolビューの表示Arrow symbol問題] を選択します。

フォーム Bean の定義

2 つの Web ページのモデルを作成するために、フォーム Bean を定義する必要があります (「Web ページのモデルおよびフローの定義」を参照)。

[Manager Review] ペインの内部クラスとして、次の 3 つのフォーム Bean を作成します。

フォーム Bean の作成

  1. [ページ フロー エクスプローラ] で、[フォーム Bean] を右クリックし、[新しい内部クラス フォーム Bean] を選択します (図 7-6 を参照)。
  2. 図 7-6 新しい内部クラス フォーム Bean


    [新しい内部クラス フォーム Bean]

  3. NewFormBean というデフォルトの名前を持つ新しいフォーム Bean が作成されます。
  4. [NewFormBean] を右クリックArrow symbol[名前の変更] を選択して、名前を ManagerReviewForm にします。
  5. 手順 1 および手順 3 を繰り返して、名前をそれぞれ AssetSummaryForm および AssetForm にします (図 7-7 を参照)。
  6. 図 7-7 フォーム Bean


    フォーム Bean

ManagerReviewForm の定義
  1. ManagerReviewForm には、以下の変数およびデータ型が含まれます。
    • Name (String)
    • SSN (String)
    • LoanAmount (Int)
    • NotesProp (PropertyInstanceHolder)
    • CollateralAssets (String)
  2. 上記の変数を選択して ManagerReview.java ソース ビューに配置します。
  3. 変数を選択し、[ソースArrow symbolGetter および Setter の生成] を選択します。
  4. [Getter および Setter の生成] ダイアログ ボックスが表示されます。

  5. プロパティの変更可能な変数を選択します (図 7-8)。
  6. 図 7-8 [Getter および Setter の生成] ダイアログ ボックス


    [Getter および Setter の生成] ダイアログ ボックス

  7. [OK] をクリックします。

変数を定義すると、クラスは以下のようになります。

@Jpf.FormBean
public static class ManagerReviewForm implements java.io.Serializable {
rivate static final long serialVersionUID = 746621147L;
    
        private String _name;
        private String _ssn;
        private int _loanAmount;
        private PropertyInstanceHolder _notesProp;
        private String _collateralAssets;
        public int getLoanAmount() { return _loanAmount; }
        public void setLoanAmount(int loanAmount) { _loanAmount = loanAmount; }
        public String getName() { return _name; }
        public void setName(String name) { _name = name; }
        public String getSsn() { return _ssn; }
public void setSsn(String ssn) { _ssn = ssn; }
        public PropertyInstanceHolder getNotesProp() { return _notesProp; }         
public void setNotesProp(PropertyInstanceHolder notesProp) 
     _notesProp = notesProp; }
        public String getCollateralAssets() { return _collateralAssets; }
        public void setCollateralAssets(String collateralAssets) {
            _collateralAssets = collateralAssets; }
    }
注意 : serialVersionUID の値はさまざまです。この値は自動生成されるため、ここで表示されているものと異なる場合があります。
AssetSummaryForm の定義
  1. AssetSummaryForm には、以下のプロパティおよびデータ型が含まれます。
    • Name (String)
    • Ssn (String)
    • Assets (SortedSet<AssetForm>)
    • CreditScore (int)
  2. ManagerReviewForm の手順 2 および手順 3 を繰り返します。
  3. 上記のプロパティの変数を選択します。
  4. [OK] をクリックします。
  5. AssetSummaryForm に、以下のコードを入力します。
  6. public java.util.SortedSet<AssetForm> getAssets() { return _assets; }
    public int getCreditScore() { return _creditScore; }

    変数を定義すると、クラスは以下のようになります。

    @Jpf.FormBean
        public static class AssetSummaryForm
        implements java.io.Serializable {
            private static final long serialVersionUID = 1517513921L;
            private java.util.SortedSet<AssetForm> _assets;
            private int _creditScore;
            private String _name;
            private String _ssn;
            public AssetSummaryForm() {
                _assets = new java.util.TreeSet<AssetForm>();
            }
            public String getName() { return _name; }
            public void setName(String name) { _name = name; }
            public String getSsn() { return _ssn; }
            public void setSsn(String ssn) { _ssn = ssn; }        
            public java.util.SortedSet<AssetForm> getAssets() { return _assets; }
            public int getCreditScore() { return _creditScore; } 
        }
注意 : serialVersionUID の値はさまざまです。この値は自動生成されるため、ここで表示されているものと異なる場合があります。

AssetSummaryForm で、以下のコードを追加して、フォーム Bean が資産および信用度情報を読み込めるようにします。

この情報は、このチュートリアルの目的には十分な程度の、非常に単純化された方法 (プロパティ ファイル) で読み込まれます。実際のアプリケーションでは多くの場合、この情報は Java API または外部システムへの Web サービスという形で取得されます。

ページ フローのアクションの実装では、以下のコードに含まれている loadSummaryInfo メソッドを使用し、名前変数によって与えられたユーザの資産および信用度情報で、AssetSummaryForm オブジェクトを初期化します。

public void loadSummaryInfo(HttpSession session) {
            loadCreditScore(session);
            loadAssets(session);
        }
        public int getTotalActualAssetValue() {
            int total = 0;
            for (AssetForm asset: _assets) {
                total = asset.getActualValue();
            }
            return total;
        }
        protected void loadCreditScore(HttpSession session) {
            // プロパティとして信用度を読み込みます
            String resourceName = "/creditRatings/creditRatings.properties";
            java.util.Properties props =
loadProperties(resourceName, session);
            _creditScore = getIntProperty(props, _name);
        }
        protected void loadAssets(HttpSession session) {
            // プロパティとして資産を読み込みます
            String resourceName = "/assets/" + _name + ".properties";
            java.util.Properties props =
loadProperties(resourceName, session);
            String assetList = props.getProperty("assetList");
            if (assetList != null) {
            	java.util.StringTokenizer st = new java.util.StringTokenizer(assetList, ",");
                while (st.hasMoreTokens()) {
                    String assetName = st.nextToken().trim();
                    AssetForm asset = new AssetForm();
                    asset.setName(assetName);
                    int value =
                        getIntProperty(props, assetName + "." + "value");
                    asset.setValue(value);
                    int amountOwed =
                        getIntProperty(props, assetName + "." + "amountOwed");
asset.setAmountOwed(amountOwed);
                    _assets.add(asset);
                }
            }
        }
        protected java.util.Properties
        loadProperties(String resourceName, HttpSession session) {
            // プロパティとしてリソースを読み込みます
            java.io.InputStream is = null;
            try {
                is = session.getServletContext().
                    getResourceAsStream(resourceName);
                java.util.Properties props = new java.util.Properties();
                if (is != null) {
                    props.load(is);
                }
                return props;
            } catch (Exception e) {
                // TODO : 処理の改善
                e.printStackTrace();
            } finally {
                if (is != null) {
                    try { is.close(); } catch (Exception e) { e.printStackTrace(); }
                }
            }
            return new java.util.Properties();
        }
        
        private int getIntProperty(java.util.Properties props, String key) {
            String value = props.getProperty(key);
            if (value == null) {
                return 0;
            }
            return Integer.valueOf(value);
        }

上記の手順が完了すると、ページ フローに begin() メソッドがないというコンパイル エラーが表示されます。

AssetForm の定義
  1. AssetForm には、以下のプロパティおよびデータ型が含まれます。
    • Name (String)
    • Value (int)
    • AmountOwed (int)
    • TotalValue (int)
  2. ManagerReviewForm の手順 2 および手順 3 を繰り返します。
  3. 上記のプロパティの変数を選択します。
  4. [OK] をクリックします。
  5. 変数を定義すると、クラスは以下のようになります。

    @Jpf.FormBean
        public static class AssetForm
        implements java.io.Serializable, Comparable {
            private static final long serialVersionUID = 1491696939L;
            private String _name;
            private int _value;
            private int _amountOwed;
            
            public int getAmountOwed() {
                return _amountOwed;
            }
            public void setAmountOwed(int lienValue) {
                _amountOwed = lienValue;
            }
            public String getName() {
                return _name;
            }
            public void setName(String name) {
                _name = name;
            }
            public int getValue() {
                return _value;
            }
            public void setValue(int value) {
                _value = value;
            }
            public int getActualValue() {
                return _value - _amountOwed;
            }
        }
注意 : serialVersionUID の値はさまざまです。この値は自動生成されるため、ここで表示されているものと異なる場合があります。

上記の手順が完了すると、AssetForm クラスが、継承した抽象メソッド Comparable.compareTo(Object) を実装する必要があるというコンパイル エラーが表示されます。このエラーを解決するには、以下のメソッドをコピーして、AssetForm クラス内に貼り付けます。このコードにより、資産概要 Web ページで、個々の資産項目を合計の資産価値の降順に並べ替えることができるようになります。

public int compareTo(Object o) {
            if (!(o instanceof AssetForm)) {
                return 0;
            }
            AssetForm other = (AssetForm)o;
            int otherActualValue = other._value - other._amountOwed;
            return otherActualValue - getActualValue();
        }

AssetForm クラスの最後に以下のメソッドを追加します。このメソッドは、後で定義する JSP ページから「実際の」資産価値を取得するために使用されます。

public int getActualValue() {
return _value - _amountOwed;

資産サポート情報ファイルの定義

John Smith (このスペルおよび大/小文字表記を使用) という名前の人物の融資要求をサポートするための情報を、以下のように定義します。

  1. [パッケージ・エクスプローラー] ペインで、[Loan_Web] を展開します。
  2. [WebContent] を右クリックArrow symbol[新規Arrow symbolフォルダー] を選択します。
  3. [新規フォルダー] ダイアログ ボックスが表示されます (図 7-9 を参照)。

    図 7-9 新規フォルダー


    新規フォルダー

  4. [フォルダー名] に assets と入力し、[終了] をクリックします。
  5. 新しいフォルダをもう 1 つ作成し、[フォルダー名] に creditRatings と入力し、[終了] をクリックします。
  6. [asset] を右クリックし、[新規|ファイル] を選択します。
  7. [新規ファイル] ダイアログ ボックスが表示されます。

  8. [ファイル名] に John Smith.properties と入力し、[終了] をクリックします。
  9. 作成したファイルがエディタに表示されます。

  10. エディタに、以下の詳細を入力します。
  11. assetList=Home, Car

    Home.value=300000

    Home.amountOwed=290000

    Car.value=20000.

    Car.amountOwed=19000

  12. [creditRatings] を右クリックし、[新規ファイル] を選択します。
  13. [ファイル名] に CreditRating.properties と入力し、[終了] をクリックします。
  14. 以下の詳細を、プロパティ ファイルに 1 行で (表示されているとおり正確に) 入力します。
  15. John\ Smith=100.

ページ フローでのアクションの定義

ページ フローでの、管理者審査ページと資産概要ページ間を移動するアクション、およびタスクでの承認アクションと拒否アクションを実行するアクションを定義します。ページ フローのアクションは、ページ フロー コントローラのメソッドです。このメソッドにより、UI が新しいページに進み、必要に応じて結果が計算され、進むページにフォーム Bean が渡されます。

フォーム Bean はアクションから Web ページに渡され、、ページの表示フィールドに値が設定されます。その後、処理のために Web ページがサーバに送信されたときに、Web ページ上のフィールドの値が収集され、フォーム Bean のプロパティに設定されます。

アクション メソッドは、フォーム Bean をアクション メソッドのパラメータとして定義することで、Web ページの送信ボタンをクリックして入力されたフォーム Bean を受け入れることができます。この例としては、以下の「承認」アクションを参照してください。アクション メソッドは、アクションが転送されているターゲットの Web ページに、フォーム Bean を渡すこともできます。これは、Forward オブジェクト (自身に設定されたフォーム Bean を持っている) を渡すことで実行されます。この例としては、以下の「show asset summary」アクションを参照してください。この例としては、以下の「承認」アクションを参照してください。

以下の、初期化のアクションを定義します。

以下の、ページ移動のアクションを定義します。

注意 : 上記の 2 つのアクションは、互いに連携する関係にあります。このことは、周期的に 2 つのページを移動する目的を反映しています。

以下の、タスクでのユーザ アクションを処理するためのアクションを定義します。

以下では、新しいアクションを追加する方法について説明します。以下の手順およびページ フローのアクション ウィザードに従って、上記のすべてのアクションを追加できます (その後、「アクション メソッドの実装」で示されているアクション メソッド本体のコードをコピー/ペーストします)。または、以下の「アクション メソッドの実装」で示されているアクションの宣言およびアクション メソッドの完全なコードをそのままコピー アンド ペーストして、次の手順をすべて省略することもできます。

アクションの作成

  1. [ページ フロー エクスプローラ] で、[アクション] を右クリックして、[新しいアクション] を選択します。
  2. [新しいアクション] ダイアログ ボックスが表示されます (図 7-10 を参照)。

    図 7-10 新しいアクション


    新しいアクション

  3. 新しいアクションを 5 つ作成し、表 7-1 に示すように、詳細を入力します。
    表 7-1 新しいアクションの設定
    アクション名
    アクション テンプレート
    フォーム Bean
    転送先
    begin
    基本
    <なし>
    <なし>
    viewAssetSummaryAction
    基本
    ManagerReviewForm
    <なし>
    returnToManagerReviewAction
    基本
    AssetSummaryForm
    <なし>
    approveLoanAction
    基本
    ManagerReviewForm
    <なし>
    rejectLoanAction
    基本
    ManagerReviewForm
    <なし>

次に、先ほど定義したアクション メソッドの、メソッド本体を実装する必要があります。

すべてのアクション メソッドのコードを以下に示します。各アクション メソッドの @Jpf.Action アノテーションとともにアクション シグネチャをコピーしていることを確認してください。

アクション メソッドの実装

上記の節で説明されている各アクション メソッドで、以下を行います。

アクション ウィザードを使用してアクション メソッドを作成しない場合は、以下を行う必要があります。

アクション ウィザードを使用してアクション メソッドを作成した場合は、以下を行う必要があります。

アクション メソッド、フォーム Bean および UseFormBean フィールド

アクション メソッドは、フォーム Bean を受け入れ、フォーム Bean を使用してページに転送できます。Web フォームを送信するとき、および送信に関連付けられているアクションを呼び出しているときに、デフォルトでは、NetUI フレームワークが (フォーム Bean クラスの、引数を持たないパブリックコンストラクタを使用して) 新しいフォーム Bean インスタンスを作成します。その後、この新しい Bean インスタンスに、Java Reflection を介して、送信された Web ページ フォームのデータ バインディング タグからのデータが入力されます。

このプロセスには、いくつかの制限があります。たとえば、Web ページの JSP タグに示されない、一時的な非表示の情報がフォーム Bean に含まれている場合、アクション メソッドに実際に渡されるフォーム Bean (NetUI フレームワークによって作成された Bean) はこの情報を見つけられません。

アクション メソッドが呼び出されるたびに、新しい Bean の作成によるオーバーヘッドや動作上の問題が発生しないように、アクション メソッドの @Jpf.Action アノテーションに useFormBean フィールドを指定できます。これにより、コントローラが、ページ フロー コントローラの状態フォーム Bean の 1 つのコピーを保持できるようになり、アクション メソッドは、新しいフォーム Bean オブジェクトを作成せずに、その状態からオブジェクトを取得できるようになります。

前の節で示されているアクション メソッドのコードで、useFormBean 機能を利用します。このコードを機能させるには、ページ フロー コントローラでメンバー変数を定義して、後で渡すフォーム Bean を保持する必要があります。

ManagerReview クラスの最上部に、次のメンバー関数を追加します。

private ManagerReviewForm _managerReviewForm; // 要求間でフォームを保持するため

ManagerReviewForm パラメータを取得するアクション メソッドが、@Jpf.Action アノテーションに useFormBean 属性を指定していない場合は、指定します。たとえば、rejectLoanAction の @Jpf.Action アノテーションは、以下のようになっています。

@Jpf.Action(forwards = {
        @Jpf.Forward(name = "success",
                     action = "stepDoneAction")
    }, useFormBean = "_managerReviewForm")

追加する必要のあるテキストは、上記のコードの強調表示されている部分です。

ワークリスト プロパティ エディタとアクション

ワークリストには、カスタム タスク UI のプロパティを編集するための組み込みサポートが用意されています。この組み込みサポートには、JSP タグ、デフォルトのエディタ、および基本の TaskUIPageFlowController のヘルパー メソッドがあります。これらの機能により、用意された UI を使用して次のタイプのプロパティを容易に編集できます。

さらに、プロパティ エディタ機能により、上記の複雑な型で、スタンドアロン エディタだけでなく、インライン エディタ (簡単なフォーム フィールド) も使用してプロパティの編集が容易にサポートできるようになります。この機能によって、面倒なプロパティの編集が非常に容易になります。このチュートリアルで定義される管理者審査 Web ページは、Notes と CollateralAssets の 2 つのプロパティを編集します。Worklist のプロパティ エディタ機能を使用して Notes プロパティを編集し、簡単な NetUI データ バインディング タグを使用して、CollateralAssets プロパティを編集します。

このチュートリアルでのプロパティ エディタ機能の使用には、複数の構成要素があります。

タスクのユーザ プロパティ エディタを処理するための以下のアクションを定義します。

ページ フローでのアクションの定義」の節で説明されている、アクションの追加手順を使用して、表 7-2 で示されている以下のアクションを追加します。

表 7-2
アクション名
アクション テンプレート
フォーム Bean
転送先
editNotesPropAction
基本
ManagerReviewForm
<なし>
okPropAction
基本
com.bea.wli.datatype.EditorValueHolder
<なし>
cancelPropAction
基本
<なし>
<なし>
ページ フローでのアクションの定義
注意 : com.bea.wli.datatype.EditorValueHolder を追加する場合は、フォーム Bean の入力フィールドの横にある [追加] ボタンをクリックする必要があります。これにより、検索ウィンドウが開きます。EditorValueHolder と入力すると、このクラスが検索されます。エントリをクリックして、[OK] を押します。

上記の 3 つのアクションに対する以下のコードを、ManagerReview ページ フロー コントローラに挿入します。

private transient com.bea.wli.datatype.EditorValueHolder _editorValue; // 効率化のため
    /**
     * このアクションは、GetManagerReview.jsp および Worklist の
     * propertyEditor タグからの「スタンドアロン エディタの起動」
     * 呼び出しを処理します。(editPropActionHelper を介して) スタンドアロン
     *  エディタの URI を算出し、その URI に進みます。このエディタは
     * ネストされたページ フローであり、既知のアクションである
     *  okPropAction と cancelPropAction を介してこのコントローラ (呼び出し元)
     *  に戻ります。ManagerReviewForm フォーム Bean を渡して、
     * この呼び出しで再作成されないようにします。
     */
    @Jpf.Action(useFormBean="_managerReviewForm")
public Forward editNotesPropAction(ManagerReviewForm form)
        throws com.bea.wli.worklist.api.ManagementException, 
        com.bea.wli.datatype.DataTypeException {
        // スーパークラスから編集可能なプロパティを取得
        // します。これらは、スーパークラスに含まれる
        // UpdateActionForm からも取得できます。
        // UpdateActionForm は、スーパークラスによって管理され、
        // タスク (PropertyInstanceHolder として示される) の
        // 編集可能なプロパティを含んでいます。
        // 汎用タスク UI は、UpdateActionForm を使用できます。
        // 単にメイン ページのフォーム Bean として使用できます。
        com.bea.wli.worklist.portal.PropertyInstanceHolder[] properties =
            getTaskEditablePropertiesMap().
                values().toArray(new com.bea.wli.worklist.portal.PropertyInstanceHolder[0]);
        // 注意 : ここで、propertyEditor タグの属性 (hostPage など) を
        //       格納できます。
        //       これにより、編集が (okPropAction を介して) 完了
        //       または (cancelPropAction を介して) 中断した場合に、
        //       適切なページに戻ることができます。
        
        // これは、JSP ページで選択したプロパティの編集を
        // 開始します (また、このメソッドで、
        // 受信する HTTP 要求に名前が設定されます)。
        Forward forward = editPropActionHelper(properties);
        return forward;
    }
    /**
     * [OK] をクリックして編集を適用すると、(editNotesPropAction で転送された) 
     * スタンドアロン エディタがこのアクションに戻ります。
     * スタンドアロンのエディタは、エディタで作成/編集された値を保持する 
     EditorValueHolder を渡して、このアクションに戻ります。
     * この _editorValue を、useFormBean に渡すことで、
     * 大きくなる可能性のあるフォーム Bean のコピーの作成を回避します。
     */
    @Jpf.Action(loginRequired = true,
                forwards = {
                    @Jpf.Forward(name = "backToManagerReview",
                                 path = "GetManagerReview.jsp")
                },
                useFormBean = "_editorValue")
    protected Forward okPropAction(com.bea.wli.datatype.EditorValueHolder value)
        throws Exception {
        okPropActionHelper(value);
        return new Forward("backToManagerReview", _managerReviewForm);
    }
    /**
     * エディタで、ユーザが [取り消し] をクリックした場合に、
     * (editNotesPropAction で起動された) スタンドアロン エディタが 
     * 呼び出すアクションです。
     * @return
     * @throws Exception
     */
    @Jpf.Action(loginRequired = true,
                forwards = {
                    @Jpf.Forward(name = "backToManagerReview",
                                 path = "GetManagerReview.jsp")
                })
    protected Forward cancelPropAction()
        throws Exception {
        cancelPropActionHelper();
        return new Forward("backToManagerReview", _managerReviewForm);
    }
ページ フローの最終コード
上記の手順を完了すると、ページ フローのコードは以下のようになります。
package manager;
import javax.servlet.http.HttpSession;
import org.apache.beehive.netui.pageflow.Forward;
import org.apache.beehive.netui.pageflow.annotations.Jpf;
import com.bea.wli.worklist.portal.PropertyInstanceHolder;
import com.bea.wli.worklist.portal.TaskUIPageFlowController;
@Jpf.Controller(nested = true)
public class ManagerReview extends TaskUIPageFlowController {
	private static final long serialVersionUID = -1579985639L;
    private ManagerReviewForm _managerReviewForm; // 要求間でフォームを保持するため。
    @Jpf.Action(forwards = { @Jpf.Forward(name = "done", returnAction = "managerDone") })
	protected Forward done() {
		return new Forward("done");
	}
    /**
     * このコントローラを初期化し、スーパークラスのヘルパーを呼び出して、
     * 取得した内容を初期化します。
     * これには、タスク コンテキスト、タスクおよびアクションの標準のフォーム Bean、
     * およびプロパティ編集サポートが含まれます。
     */
	@Jpf.Action(forwards = {
        @Jpf.Forward(name="success", path="GetManagerReview.jsp")
    })
	public Forward begin() throws Exception {
        
        // 基本クラスのヘルパーを初期化して、
        // このコントローラを通じて使用できるようにします。
		beginActionHelper();
        // ManagerReviewForm を作成して、基本クラスのヘルパーによって
        // 取得されるプロパティ値とともに読み込みます
        _managerReviewForm = new ManagerReviewForm();
        _managerReviewForm.setName(
            (String)getTaskPropertiesMap().
                get("Name").getValue());
        _managerReviewForm.setSsn(
                (String)getTaskPropertiesMap().
                    get("SSN").getValue());
        _managerReviewForm.setLoanAmount(
                ((Long)getTaskPropertiesMap().
                    get("LoanAmt").getValue()).intValue());
        // 編集可能な notes プロパティを取得します。
        // この PropertyInstanceHolder を使用して、Worklist で提供される
        // ヘルパーを介して notes プロパティを編集するためです。
        PropertyInstanceHolder notesProp =
            getTaskEditablePropertiesMap().
                get("Notes");
        _managerReviewForm.setNotesProp(notesProp);
        return new Forward("success", _managerReviewForm);
	}
    /**
     * 資産のサブ フォームに進み、
     * 検出した融資申し込み者の資産を表示します。
     */
	@Jpf.Action(forwards = {
        @Jpf.Forward(name = "success",
                     path = "AssetSummary.jsp")
        }, useFormBean = "_managerReviewForm"
    )
public Forward viewAssetSummaryAction(ManagerReviewForm form) {
        
        AssetSummaryForm assetSummaryForm = new AssetSummaryForm();
        assetSummaryForm.setName(form.getName());
        assetSummaryForm.setSsn(form.getSsn());
        assetSummaryForm.loadSummaryInfo(getSession());
        
        return new Forward("success", assetSummaryForm);
    }
    /**
     * 資産を確認した後で、メイン フォームに戻ります。
     */
    @Jpf.Action(forwards = {
        @Jpf.Forward(name = "success",
                     path = "GetManagerReview.jsp")
    })
    public Forward returnToManagerReviewAction(AssetSummaryForm form) {
        Forward forward = new Forward("success", _managerReviewForm);
        return forward;
    }
    
    /**
     * スーパークラスのヘルパーおよび ManagerReviewForm に
     * 格納しているプロパティを使用して、融資を承認します。
     * useFormBean 属性を指定して、ManagerReviewForm のコピーを
     *  1 つ保持します。
     * 注意 : このアクションは、(メイン フォームにフィールドを
     *       直接置く代わりに) アクション プロパティ ページに進み、
     *       アクションのプロパティを収集するように設計されています。
     *       別のページが必要な場合は、showStepActionActionHelper を呼び出して、
     *       TakeStepActionActionForm がこれらのプロパティを取得できるように
     *       することができます。このフォームは、アクション プロパティ フォームで
     *       propertyEditor タグとともに使用するのに適しています。
     * @see TaskUIPageFlowController#showStepActionActionHelper(com.bea.wli.worklist.api.tasktype.StepAction)
     * @see TaskUIPageFlowController#takeStepActionActionHelper(com.bea.wli.worklist.portal.TakeStepActionActionForm)
     * @see TaskUIPageFlowController#isPostActionInteractiveAssignment(java.lang.String)
     * @see TaskUIPageFlowController#takeStepActionAndClaimActionHelper(com.bea.wli.worklist.portal.TakeStepActionActionForm, java.lang.String)
     */
    @Jpf.Action(forwards = {
        @Jpf.Forward(name = "success",
                     action = "stepDoneAction")
    }, useFormBean="_managerReviewForm")
    public Forward approveLoanAction(ManagerReviewForm form)
        throws Exception {
        // アクションに渡すプロパティ値のマップを構築します
        java.util.Map<String, String> propMap 
        	= new java.util.HashMap<String, String>();
        propMap.put("Notes", form.getNotesProp().getEditorValueAsString());
        propMap.put("CollateralAssets", form.getCollateralAssets());
        // ここで、アクションを実行します。
        this.takeStepAction(getCurrentStep().getName(),
                            "Approve",
                            propMap);
        Forward forward = new Forward("success");
        return forward;
    }
    /**
     * スーパークラスのヘルパーを使用して、融資を拒否します。
     * useFormBean 属性を指定して、ManagerReviewForm のコピーを
     *  1 つ保持します。
     * 注意 : このアクションは、(メイン フォームにフィールドを
     *       直接置く代わりに) アクション プロパティ ページに進み、
     *       アクションのプロパティを収集するように設計されています。
*       別のページが必要な場合は、showStepActionActionHelper を呼び出して、
     *       TakeStepActionActionForm がこれらのプロパティを取得できるように
     *       することができます。このフォームは、アクション プロパティ フォームで
     *       propertyEditor タグとともに使用するのに適しています。
     * @see TaskUIPageFlowController#showStepActionActionHelper(com.bea.wli.worklist.api.tasktype.StepAction)
     * @see TaskUIPageFlowController#takeStepActionActionHelper(com.bea.wli.worklist.portal.TakeStepActionActionForm)
     * @see TaskUIPageFlowController#isPostActionInteractiveAssignment(java.lang.String)
     * @see TaskUIPageFlowController#takeStepActionAndClaimActionHelper(com.bea.wli.worklist.portal.TakeStepActionActionForm, java.lang.String)
     */
    @Jpf.Action(forwards = {
        @Jpf.Forward(name = "success",
                     action = "stepDoneAction")
    }, useFormBean="_managerReviewForm")
    public Forward rejectLoanAction(ManagerReviewForm form)
        throws Exception {
        // アクションに渡すプロパティ値のマップを構築します
        java.util.Map<String, String> propMap 
        	= new java.util.HashMap<String, String>();
        propMap.put("Notes", form.getNotesProp().getEditorValueAsString());
        // ここで、アクションを実行します。
        this.takeStepAction(getCurrentStep().getName(),
                            "Reject",
                            propMap);
        Forward forward = new Forward("success");
        return forward;
    }
	/**
	 * このコントローラのインスタンスが作成されたときに呼び出されるコールバックです。
	 */
	@Override
	protected void onCreate() {
	}
	/**
	 * このコントローラのインスタンスが破棄されたときに呼び出されるコールバックです。
	 */
	@Override
	protected void onDestroy(HttpSession session) {
	}
    private transient com.bea.wli.datatype.EditorValueHolder _editorValue; // 効率化のため
    
    /**
     * このアクションは、GetManagerReview.jsp および Worklist の
     * propertyEditor タグからの「スタンドアロン エディタの起動」
     * 呼び出しを処理します。(editPropActionHelper を介して) スタンドアロン
     *  エディタの URI を算出し、その URI に進みます。このエディタは
     * ネストされたページ フローであり、既知のアクションである
     *  okPropAction と cancelPropAction を介してこのコントローラ (呼び出し元)
     * に戻ります。ManagerReviewForm フォーム Bean を渡して、
     * この呼び出しで再作成されないようにします。
     */
    @Jpf.Action(useFormBean="_managerReviewForm")
    public Forward editNotesPropAction(ManagerReviewForm form)
        throws com.bea.wli.worklist.api.ManagementException, 
        com.bea.wli.datatype.DataTypeException {
        // スーパークラスから編集可能なプロパティを取得
        // します。これらは、スーパークラスに含まれる
        // UpdateActionForm からも取得できます。
        // UpdateActionForm は、スーパークラスによって管理され、
        // タスク (PropertyInstanceHolder として示される) の
        // 編集可能なプロパティを含んでいます。
        // 汎用タスク UI は、UpdateActionForm を使用できます。
*       別のページが必要な場合は、showStepActionActionHelper を呼び出して、
     *       TakeStepActionActionForm がこれらのプロパティを取得できるように
     *       することができます。このフォームは、アクション プロパティ フォームで
     *       propertyEditor タグとともに使用するのに適しています。
     * @see TaskUIPageFlowController#showStepActionActionHelper(com.bea.wli.worklist.api.tasktype.StepAction)
     * @see TaskUIPageFlowController#takeStepActionActionHelper(com.bea.wli.worklist.portal.TakeStepActionActionForm)
     * @see TaskUIPageFlowController#isPostActionInteractiveAssignment(java.lang.String)
     * @see TaskUIPageFlowController#takeStepActionAndClaimActionHelper(com.bea.wli.worklist.portal.TakeStepActionActionForm, java.lang.String)
     */
    @Jpf.Action(forwards = {
        @Jpf.Forward(name = "success",
                     action = "stepDoneAction")
    }, useFormBean="_managerReviewForm")
    public Forward rejectLoanAction(ManagerReviewForm form)
        throws Exception {
        // アクションに渡すプロパティ値のマップを構築します
        java.util.Map<String, String> propMap 
        	= new java.util.HashMap<String, String>();
        propMap.put("Notes", form.getNotesProp().getEditorValueAsString());
        // ここで、アクションを実行します。
        this.takeStepAction(getCurrentStep().getName(),
                            "Reject",
                            propMap);
        Forward forward = new Forward("success");
        return forward;
    }
	/**
	 * このコントローラのインスタンスが作成されたときに呼び出されるコールバックです。
	 */
	@Override
	protected void onCreate() {
	}
	/**
	 * このコントローラのインスタンスが破棄されたときに呼び出されるコールバックです。
	 */
	@Override
	protected void onDestroy(HttpSession session) {
	}
    private transient com.bea.wli.datatype.EditorValueHolder _editorValue; // 効率化のため
    
    /**
     * このアクションは、GetManagerReview.jsp および Worklist の
     * propertyEditor タグからの「スタンドアロン エディタの起動」
     * 呼び出しを処理します。(editPropActionHelper を介して) スタンドアロン
     *  エディタの URI を算出し、その URI に進みます。このエディタは
     * ネストされたページ フローであり、既知のアクションである
     *  okPropAction と cancelPropAction を介してこのコントローラ (呼び出し元)
     *  に戻ります。ManagerReviewForm フォーム Bean を渡して、
     * この呼び出しで再作成されないようにします。
     */
    @Jpf.Action(useFormBean="_managerReviewForm")
    public Forward editNotesPropAction(ManagerReviewForm form)
        throws com.bea.wli.worklist.api.ManagementException, 
        com.bea.wli.datatype.DataTypeException {
        // スーパークラスから編集可能なプロパティを取得
        // します。これらは、スーパークラスに含まれる
        // UpdateActionForm からも取得できます。
        // UpdateActionForm は、スーパークラスによって管理され、
        // タスク (PropertyInstanceHolder として示される) の
        // 編集可能なプロパティを含んでいます。
        // 汎用タスク UI は、UpdateActionForm を使用できます。
public String getSsn() { return _ssn; }
        public void setSsn(String ssn) { _ssn = ssn; }
        public PropertyInstanceHolder getNotesProp()  
{ return _notesProp; }                  
        public void setNotesProp(PropertyInstanceHolder notesProp)  
{ _notesProp = notesProp; }
        public String getCollateralAssets() { return _collateralAssets; }
        public void setCollateralAssets(String collateralAssets) {
            _collateralAssets = collateralAssets; }
    }
    @Jpf.FormBean
    public static class AssetSummaryForm implements java.io.Serializable {
	private static final long serialVersionUID = 1517513921L;
		
        private java.util.SortedSet<AssetForm> _assets;
        private int _creditScore;
        private String _name;
        private String _ssn;
        
        public AssetSummaryForm() {
            _assets = new java.util.TreeSet<AssetForm>();
        }
        public String getName() { return _name; }
        public void setName(String name) { _name = name; }
        public String getSsn() { return _ssn; }
        public void setSsn(String ssn) { _ssn = ssn; }        
        public java.util.SortedSet<AssetForm> getAssets() { return _assets; }
        // 注意 : assets プロパティのセッターがありません。内部でこれを読み込みます。
        public int getCreditScore() { return _creditScore; }        
        // 注意 : creditScore のセッターがありません。内部でこれを読み込みます。
        public void loadSummaryInfo(HttpSession session) {            
            loadCreditScore(session);
            loadAssets(session);
        }
        public int getTotalActualAssetValue() {
            int total = 0;
            for (AssetForm asset: _assets) {
                total = asset.getActualValue();
            }
            return total;
        }
        protected void loadCreditScore(HttpSession session) {
            // プロパティとして信用度を読み込みます
            String resourceName = "/creditRatings/creditRatings.properties";
            java.util.Properties props =
                loadProperties(resourceName, session);
            _creditScore = getIntProperty(props, _name);
        }
        protected void loadAssets(HttpSession session) {
            // プロパティとして資産を読み込みます
            String resourceName = "/assets/" + _name + ".properties";
            java.util.Properties props =
                loadProperties(resourceName, session);                
            String assetList = props.getProperty("assetList");
            if (assetList != null) {
            	java.util.StringTokenizer st = new java.util.StringTokenizer(assetList, ",");
                while (st.hasMoreTokens()) {
                    String assetName = st.nextToken().trim();
                    AssetForm asset = new AssetForm();
                    asset.setName(assetName);
                    int value =
                        getIntProperty(props, assetName + "." + "value");
                    asset.setValue(value);
                    int amountOwed =
                        getIntProperty(props, assetName + "." + "amountOwed");
                    asset.setAmountOwed(amountOwed);  
                    _assets.add(asset);
                }
            }
        }
        
        protected java.util.Properties
        loadProperties(String resourceName, HttpSession session) {
            // プロパティとしてリソースを読み込みます
            java.io.InputStream is = null;
            try {
                is = session.getServletContext().
                    getResourceAsStream(resourceName);
                java.util.Properties props = new java.util.Properties();
                if (is != null) {
                    props.load(is);
                }
                return props;
            } catch (Exception e) {
                // TODO : 処理の改善
                e.printStackTrace();
            } finally {
                if (is != null) {
                    try { is.close(); } catch (Exception e) { e.printStackTrace(); }
                }
            }
            return new java.util.Properties();
        }
        
        private int getIntProperty(java.util.Properties props, String key) {
            String value = props.getProperty(key);
            if (value == null) {
                return 0;
            }
            return Integer.valueOf(value);
        }
        
    }
    @Jpf.FormBean
    public static class AssetForm implements java.io.Serializable, Comparable {
		private static final long serialVersionUID = 1491696939L;
	
        private String _name;
        private int _value;
        private int _amountOwed;
        
        public int getAmountOwed() {
            return _amountOwed;
        }
        public void setAmountOwed(int lienValue) {
            _amountOwed = lienValue;
        }
        public String getName() {
            return _name;
        }
        public void setName(String name) {
            _name = name;
        }
        public int getValue() {
            return _value;
        }
        public void setValue(int value) {
            _value = value;
        }
        
        public int getActualValue() {
            return _value - _amountOwed;
        }
        public int compareTo(Object o) {
            if (!(o instanceof AssetForm)) {
                return 0;
            }
            AssetForm other = (AssetForm)o;
            int otherActualValue = other._value - other._amountOwed;
            return otherActualValue - getActualValue();
        }
    }
}

JSP ページの定義

Web ページのモデルおよびフローの定義」の画面モデルに従って、Beehive NetUI データ バインディング JSP タグを使用し、カスタム タスク UI の 2 つの JSP ページを定義して、フォーム Bean からの読み込みおよびフォーム Bean への書き込みができる Web フォームを表示します。これらのタグを使用することで、データ駆動型の JSP ページを記述するプロセスが大幅に簡素化されます。

JSP ファイルの作成

Workshop のページ フロー パースペクティブは、適切なページを定義する場合に最初に使用します。ManagerReview ページ フロー コントローラには、これまでの節で定義したアクションによって、[ページ フロー エクスプローラ] の [ページ] ノードの下に、グレー表示された 2 つの JSP ページが表示されています。

JSP ファイルを作成するには

  1. [ページ フロー エクスプローラ] で、[ページ] を右クリックします。
  2. [GetManagerReview.jspArrow symbol作成] を選択して、新しい JSP ファイルを作成します。
  3. AssetSummary.jsp についても上記の手順を繰り返します。

デフォルトの JSP コードを以下に示します。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-html-1.0" prefix="netui"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0" prefix="netui-data"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="netui-template"%>
<netui:html>
    <head>
        <netui:base/>
    </head>
    <netui:body>
       <p>Beehive NetUI JavaServer Page - ${pageContext.request.requestURI}</p>
     </netui:body>
</netui:html>
<netui:body/> タグの間にフォームの適切なテキストを挿入して、これらのページを完成します。HTML の <table> タグを使用して、これらのフォーム フィールドを整理および調整することをお勧めします。
JSP から以下のコードを削除します。
<p>Beehive NetUI JavaServer Page - ${pageContext.request.requestURI}</p>

フォームの作成とアクションへの関連付け

この手順では、すべての JSP のデータ項目を保持する <netui:form> 要素を作成し、その後で、ManagerReview ページ フロー コントローラから、そのフォームをアクションに関連付けます。これにより、フォームが、アクション メソッドで参照されているフォーム Bean に関連付けられます。この関連付けにより、フォーム Bean のデータが、JSP フォームに追加するデータ項目とバインドされます。

NetUI フォームを JSP に追加するための一般的なプロセスは以下のとおりです。

  1. [JSP デザイン パレット] が表示されていない場合は、[ウィンドウArrow symbolビューの表示Arrow symbolJSP デザイン パレット] を選択します。
  2. [JSP デザイン パレット] が表示されます (図 7-11 を参照)。

    図 7-11 JSP デザイン パレット


    JSP デザイン パレット

  3. [JSP デザイン パレット] で [NetUI] を展開し、[form] を選択します。
  4. [form] をドラッグし、JSP ソース エディタの <netui:body/> タグ内にドロップします。
  5. ドロップすると、<netui:form action=""></netui:form> のように form 要素が追加されます。

    ページ フロー コントローラのアクションにフォームを関連付けます。このチュートリアルでは、パラメータとしてフォーム Bean を取得する ManagerReview ページ フロー コントローラのアクションと form 要素を関連付けます。フォームが送信されたときに呼び出されるアクション メソッドと、フォームと関連付けるフォーム Bean の Java 型を定義するため、この関連付けは非常に重要です。関連付けられたフォーム Bean は、JSP コードの NetUI タグから、それらのタグの値と dataSource 属性を使用してアクセスできるようになります。これらの属性は、以下のように JSP 式を介してフォーム Bean のプロパティを参照します。

    actionForm.<フォーム Bean のプロパティ>
    フォーム Bean は、フォームのメソッドのペアを定義します。
    <プロパティの Java タイプ> get<プロパティ名>()
    void set<プロパティ名>(<プロパティの Java タイプ> value)

    定義する個々の Web ページの場合の例を示します。

GetManagerReview.jsp
  1. [GetManagerReview.jsp] をダブルクリックして、ソース エディタで開きます。
  2. [NetUI] から [form] を [GetManagerReview.jsp] にドラッグし、そのフォームのアクションを [approveLoanAction] に設定します。次のように、approveLoanAction が、ManagerReviewForm 型のフォーム Bean パラメータを取得することで、GetManagerReview.jsp の form タグ内のみで関連付けが行われます。
  3. actionForm.<property> -> Call method ManagerReviewForm.get<property>
  4. この呼び出しを行うために使用される ManagerReviewForm のインスタンスは、このページに転送した Forward オブジェクトで渡されたインスタンスです。ManagerReview.java のページ フロー コードでは、これらのアクションにより、以下が行われます。
    • begin()Add Data Binding Fields
    • returnToManagerReviewAction()
    • okPropAction()
    • cancelPropAction()
    • これらのすべてのアクションは、ManagerReviewForm インスタンスを含む Forward を返す必要があります。

      JSP コードは以下のようになっています。

      <%@ page language="java" contentType="text/html;charset=UTF-8"%>
      <%@taglib uri="http://beehive.apache.org/netui/tags-html-1.0" prefix="netui"%>
      <%@taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0" prefix="netui-data"%>
      <%@taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="netui-template"%>
      <netui:html>
          <head>
              <netui:base/>
          </head>
          <netui:body>
      	<netui:form action="approveLoanAction"></netui:form>
          </netui:body>
      </netui:html>
AssetSummary.JSP

<netui:form> を作成して、そのフォームのアクションを returnToManagerReviewAction に設定します。returnToManagerReviewAction は以下のように記述してください。

    @Jpf.Action(forwards = {
        @Jpf.Forward(name = "success",
                     path = "GetManagerReview.jsp"),
                     @Jpf.Forward(name = "success2",
                             path = "GetManagerReview2.jsp")
    })
    public Forward returnToManagerReviewAction(AssetSummaryForm form) {
        Forward forward = new Forward("success", _managerReviewForm);
        return forward;
    }

次のように、returnToManagerReviewAction が、AssetSummaryForm 型のフォーム Bean パラメータを取得することで、AssetSummary.jsp の form タグ内のみで関連付けが行われます。

actionForm.<property> -> Call method AssetSummaryForm.get<property>

この呼び出しを行うために使用される ManagerReviewForm のインスタンスは、このページに転送した Forward オブジェクトで渡されたインスタンスです。ManagerReview.java のページ フロー コードでは、これらのアクションにより AssetSummary.jsp に転送されます。

JSP コードは以下のようになっています。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-html-1.0" prefix="netui"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0" prefix="netui-data"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="netui-template"%>
<netui:html>
    <head>
        <netui:base/>
    </head>
    <netui:body>
	<netui:form action="returnToManagerReviewAction"></netui:form>
    </netui:body>
</netui:html>
データバインディング フィールドの追加

NetUI データ バインディング JSP タグは、JSP ページに表示するデータをフォーム Bean から取得し、<netui:form> を送信することによって、フォーム Bean にデータを設定するために必要な作業を自動化します。すべての NetUI データ バインディング タグは、それらをフォーム Bean のプロパティと関連付ける属性を持っています。一部のタグ (<netui:label> など) では、属性には「value」という名前が付いています。その他のタグ (<netui-data:repeater> など) では、属性には「dataSource」という名前が付いています。これらの属性は、プロパティ式の定義に異なる構文を使用します。属性が dataSource の場合、構文は次のようになります。

actionForm.<property>

属性が、その他のもの (<netui:label> の値など) の場合、構文は次のようになります。

${actionForm.<property>}

以下の JSP コードで、プロパティを ManagerReviewForm から JSP ページにバインドするために、actionForm 参照を使用します。これは、JSP Designer パレットから JSP コードに、該当するタグをドラッグ アンド ドロップすることで行えます。一部のタグは NetUI メニューに、その他のタグ (repeater など) は NetUI-Data メニューにあります。次の節で、JSP ファイルの最終コードを示します。

GetManagerReview.jsp の最終コード
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-html-1.0" prefix="netui"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0" prefix="netui-data"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="netui-template"%>
<netui:html>
    <head>
        <netui:base/>
    </head>
    <netui:body>
        <netui:form action="approveLoanAction">              
            <table>
                <tr>
                    <td><netui:label value="Customer Name:"/></td>
                    <td><netui:label value="${actionForm.name}"/></td>
</tr>
                <tr>
                    <td><netui:label value="SSN:"/></td>
                    <td><netui:label value="${actionForm.ssn}"/></td>
                </tr>
                <tr>
                    <td><netui:label value="Loan Amount:"/></td>
                    <td><netui:label value="${actionForm.loanAmount}"/></td>
                </tr>
                
                <tr>
                    <td colspan="2">
                        <!-- 従来の NetUI actionForm バインディングを使用して、
                             このプロパティを編集します (netui:textBox タグ
                             に注意してください) -->
                        <netui:label value="Collateral Assets:"/>
                        <netui:textBox dataSource="actionForm.collateralAssets"/>
                    </td> 
                </tr>
            </table>          
        </netui:form>
    </netui:body>
</netui:html>
Notes プロパティを処理するためのタグがありません。Worklist によって提供されるプロパティ編集のフレームワークを利用できるようにするために、propertyEditor と呼ばれる Worklist のカスタム タグを使用するため、ここでは、Notes プロパティを個別に扱います。上記の table 内の最後の <tr> 要素 (プロパティ要素 CollateralAssets を持っているもの) の前に以下のコードを挿入してください。
                <tr>
                    <td colspan="2">
                        <!-- これは、propertyEditor タグの使用方法を示します。
                             また、ラベル、合計値、およびスタンドアロン エディタが
                             使用できる場合は、スタンドアロン エディタへのリンクを
                             示します。このタグは、インプレースでのプロパティ値の編集も
                             可能にします。
                             注意 : プロパティの編集後に
                                   このページに戻るように、
                                   hostPage 属性を設定します。
                             注意 : actionName attr 属性で取得した名前を持つ
                                   コントローラで定義されたアクションが必要です。
                          -->
                        <netui:label value="Reason for Action:"/>
                        <worklist:propertyEditor dataSource="actionForm.notesProp"
                                                 propName="Notes"
                                                 readOnly="false"
                                                 hostPage="GetManagerReview.jsp"
                                                 actionName="editNotesPropAction"/>
                    </td>
                </tr>

<worklist:propertyEditor> タグ参照を有効にするには、Worklist のプレフィックスを定義して、Worklist タグの正確な URI にマップする必要があります。以下を、JSP ファイル最上部の taglib 宣言の最後に追加してください。

<%@taglib uri="http://bea.com/wli/worklist/tags-worklist-1.0" prefix="worklist"%>

propertyEditor タグは、型 PropertyInstanceHolder である actionForm.notesProp にバインドされています。このバインディングにより、propertyEditor タグは、プロパティの編集可能なプロパティ値の取得、プロパティの型の判断、その型の登録されているスタンドアロン エディタの検出、およびスタンドアロン エディタへの値の受け渡しができるようになります。

注意 : propertyEditor タグは、editNotesPropAction を参照します。このアクションは、プロパティ用にスタンドアロン エディタを起動したときに呼び出されます。ここでは明示していませんが、ManagerReview ページ フロー コントローラのコードにも、[OK] および [取り消し] ボタンがクリックされた場合に、スタンドアロン エディタが呼び出しページ フローに戻れるようにする、2 つの「return」アクション メソッドが含まれています。これらのアクションは、それぞれ、okPropAction、cancelPropAction です。
Asset Summary.jsp の最終コード

Asset Summary.jsp の最終コードを以下に示します。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-html-1.0" prefix="netui"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0" prefix="netui-data"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="netui-template"%>
<netui:html>
    <head>
        <netui:base/>
    </head>
    <netui:body>
        <netui:form action="returnToManagerReviewAction">
            <table>
                <tr>
                    <td colspan="2"><netui:label value="Assets for ${actionForm.name}"/></td>
                </tr>
                <tr>
                    <netui-data:repeater dataSource="actionForm.assets">
                        <netui-data:repeaterHeader>
                            <table border="1">
                                <tr>
                                    <td>Name</td>
                                    <td>Value</td>
                                    <td>Amount Owed</td>
                                    <td>Actual Value</td>                                    
                                </tr>
                        </netui-data:repeaterHeader>
                        <netui-data:repeaterItem>
                                <tr>
                                    <td><netui:label value="${container.item.name}"/></td>
                                    <td><netui:label value="${container.item.value}"/></td>
                                    <td><netui:label value="${container.item.amountOwed}"/></td>
                                    <td><netui:label value="${container.item.actualValue}"/></td>
                                </tr>
                        </netui-data:repeaterItem>
                        <netui-data:repeaterFooter>
                            </table>
                        </netui-data:repeaterFooter>
                    </netui-data:repeater>
                </tr>
                <tr>
                    <td><netui:label value="Credit Score:"/></td>
                    <td><netui:label value="${actionForm.creditScore}"/></td>
                </tr>
            </table>
        </netui:form>    
    </netui:body>
</netui:html>
コマンド リンクおよびコマンド ボタンの追加

フォーム間の移動およびそれらが示すタスクでのアクションの実行のための <netui:button> 要素を追加します。

GetManagerReview.jsp

<worklist:propertyEditor> タグを含んでいる <tr> 要素の前/上側に、以下のコードを挿入します。このコードは、GetManagerReview ページにアクション ボタンを表示します。このボタンは、クリックされると、viewAssetSummary アクションを呼び出し、ユーザを AssetSummary ページに転送します。

<tr>
                    <td colspan="2">
                        <netui:button value="View Asset Summary"
                                      action="viewAssetSummaryAction"/>
                    </td>
                </tr>

次に、最後の </table> タグの前に、以下のコードを挿入します。

<tr>
                    <td colspan="2">
                        <netui:button value="Approve" action="approveLoanAction"/>
                        <p/>
                        <netui:button value="Reject" action="rejectLoanAction"/>
                    </td>                       
                </tr>

これは、融資責任者が、タスクで (ページ フローの approveLoanAction および rejectLoanAction アクション メソッドを介して) 承認アクションおよび拒否アクションを実行できるようにするためのボタンを表示します。

Asset Summary.jsp

最後の table タグ (</table>) の前に、以下のコードを挿入します。

<tr>

<td colspan="2"><netui:button value="Back"/>

</tr>

これは、融資管理者が管理者審査ページに戻るための [戻る] ボタンを表示します。ここでは、アクション属性はありません。この場合、フォームからのアクション (returnToManagerReviewAction) が実行されます。

最終の JSP コード

GetManagerReview.jsp の最終の JSP コードを以下に示します。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-html-1.0" prefix="netui"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0" prefix="netui-data"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="netui-template"%>
<%@taglib uri="http://bea.com/wli/worklist/tags-worklist-1.0" prefix="worklist"%>
<netui:html>
    <head>
        <netui:base/>
    </head>
    <netui:body>
        <netui:form action="approveLoanAction">       
            <table>
                <tr>
                    <td><netui:label value="Customer Name:"/></td>
                    <td><netui:label value="${actionForm.name}"/></td>
                </tr>
                <tr>
                    <td><netui:label value="SSN:"/></td>
                    <td><netui:label value="${actionForm.ssn}"/></td>
                </tr>
                <tr>
                    <td><netui:label value="Loan Amount:"/></td>
                    <td><netui:label value="${actionForm.loanAmount}"/></td>
                </tr>
                <tr>
                    <td colspan="2">
                        <netui:button value="View Asset Summary" action="viewAssetSummaryAction"/>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <!-- これは、propertyEditor タグの使用方法を示します。
                             また、ラベル、合計値、およびスタンドアロン エディタが
                             使用できる場合は、スタンドアロン エディタへのリンクを
                             示します。このタグは、インプレースでのプロパティ値の編集も

可能にします。

注意 : プロパティの編集後に

このページに戻るように、

hostPage 属性を設定します。

注意 : actionName attr 属性で取得した名前を持つ

コントローラで定義されたアクションが必要です。

-->

<netui:label value="Reason for Action:"/>

<worklist:propertyEditor hostPage="GetManagerReview.jsp"

dataSource="actionForm.notesProp"

propName="Notes"

readOnly="false"

actionName="editNotesPropAction"/>

</td>

</tr>

<tr>

<td colspan="2">

<!-- 従来の NetUI actionForm バインディングを使用して、

このプロパティを編集します (netui:textBox タグ

に注意してください) -->

<netui:label value="Collateral Assets:"/>

<netui:textBox dataSource="actionForm.collateralAssets"/>

</td>

</tr>

<tr>

<td colspan="2">

<netui:button value="Approve" action="approveLoanAction"/><p/>

<netui:button value="Reject" action="rejectLoanAction"/>

</td>

</tr>

</table>

</netui:form>

</netui:body>

</netui:html

AssetSummary.jsp の最終の JSP コードを以下に示します。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-html-1.0" prefix="netui"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0" prefix="netui-data"%>
<%@taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="netui-template"%>
<netui:html>
    <head>
        <netui:base/>
    </head>
    <netui:body>
        <netui:form action="returnToManagerReviewAction">
            <table>
                <tr>
                    <td colspan="2"><netui:label value="Assets for ${actionForm.name}"/></td>
                </tr>
                <tr>
                    <netui-data:repeater dataSource="actionForm.assets">
                        <netui-data:repeaterHeader>
                            <table border="1">
                                <tr>
                                    <td>Name</td>
                                    <td>Value</td>
                                    <td>Amount Owed</td>
                                    <td>Actual Value</td>                                    
                                </tr>
                        </netui-data:repeaterHeader>
                        <netui-data:repeaterItem>
                                <tr>
                                    <td><netui:label value="${container.item.name}"/></td>
                                    <td><netui:label value="${container.item.value}"/></td>
                                    <td><netui:label value="${container.item.amountOwed}"/></td>
                                    <td><netui:label value="${container.item.actualValue}"/></td>
                                </tr>
                        </netui-data:repeaterItem>
                        <netui-data:repeaterFooter>
                            </table>
                        </netui-data:repeaterFooter>
                    </netui-data:repeater>
                </tr>
                <tr>
                    <td><netui:label value="Credit Score:"/></td>
                    <td><netui:label value="${actionForm.creditScore}"/></td>
</tr>
                <tr>
                    <td colspan="2"><netui:button value="Back"/>
                </tr>
            </table>
        </netui:form>    
    </netui:body>
</netui:html>

 


カスタム UI の登録

融資承認タスク プランの ManagerReviewPending ステップのためのカスタム タスク UI を設計したら、以下の LoanWeb Web プロジェクトにあるレジストリ ファイルにマッピング エントリを追加して、これらの環境で適用されるようにカスタム タスク UI を登録する必要があります。

LoanWeb/WebContent/WEB-INF/task-ui-registry.xml

この XML ファイルは、ワークリスト タスク UI レジストリのスキーマに関連付けられています。また、このスキーマは Workshop に登録されています。このファイルは、Workshop で編集する必要があります。ファイルを開くと、[デザイン] および [ソース] タブのあるエディタが表示されます。[ソース] タブの、最初のコンテンツは次のように表示されています。

<task-ui-registry xmlns="http://www.bea.com/wli/worklist/taskuiregistry">
</task-ui-registry>

[デザイン] タブのツリー ビューで、作業する任意のノードを右クリックできます。ノードの削除および子ノードの追加が行えます。

カスタム タスク UI を登録するには、以下の情報が必要です。

このチュートリアルの場合、必要な情報は以下のとおりです。

このチュートリアルでのページ フロー コントローラ ファイルは、実際は ManagerReview.java ですが、URI の末尾は .jpf になります。これは、LoanApp Web アプリケーションのサーブレット フィルタが正常に起動するようにするために必要なことです。task-ui-registry.xml の編集を最初に終了するには、[パッケージ・エクスプローラー] ビューに切り替えて、エディタの [デザイン] タブで以下を行います。

  1. [パッケージ・エクスプローラー] で、[LoanWeb] を展開し、/WebContent/WEB-INF/ に移動して、[task-ui-registry.xml] を選択します。
  2. [task-ui-registry.xml] を右クリックして、[子の追加Arrow symbolstep-override] を選択します。これにより、ルート要素に、新しい step-override 要素が追加されます (図 7-12 を参照)。
  3. 図 7-12 子の追加


    子の追加

  4. 新しく追加された step-override 要素を展開します。その下に、task-type-id、step-name、および custom-task-ui-uri の 3 つの要素が表示されます。これらはすべてデフォルト値に設定されています。
  5. これらの 3 つの各要素で、右側の値のカラムをクリックして、デフォルト値を上で示されている値で置き換えます (図 7-13 を参照)。
  6. 図 7-13 編集済み XML


    編集済み XML

 


カスタム タスク UI のデプロイ

  1. [パッケージ・エクスプローラー] ペインで、[Loan_Web] を右クリックします。
  2. [実行Arrow symbolサーバーで実行] をクリックします。
  3. [新規サーバーの定義] ダイアログ ボックスで、デフォルト設定を受け入れて、[次へ] をクリックします。
  4. Configuration Wizard を使用して作成した、myworklist ドメインを参照して選択します。このドメインは \user_projects\domains\myworklist にあります。
  5. [終了] をクリックします。

 


カスタム UI の検証

カスタム タスク UI を検証するために、以下のシナリオを使用します。

ユーザおよびグループのコンフィグレーション

融資処理のユーザおよびグループのコンフィグレーション」を参照してください。

融資承認タスクの作成

  1. 以下の資格を使用して、Loan_Web プロジェクトにログインします。
  2. ユーザ名 : weblogic

    パスワード : weblogic

  3. 期限切れ、近日中、および担当のタスクの受信ボックスであるポートレットと、新しいタスクを作成できるポートレットを持つホーム ページが表示されます。
  4. [タスクの作成] ポートレットの [/Loan/loan_approval 1.0] オプションをクリックします。[新しいタスク] ページが表示されます。
  5. [タスク名] に John Smith 向け融資と入力します。
  6. 以下の情報を入力します。
  1. [タスクの作成] をクリックします。タスクが作成されて、ホームページの [近日中のタスク] ポートレットに表示されます。
  2. [ログアウト] をクリックして終了し、weblogic として Worklist User Portal からログ アウトします。

割り当てられた融資担当者による管理者への融資の転送

  1. 以下の資格を使用して、Loan_Web プロジェクトにログインします。
  2. ユーザ名 : John

    パスワード : password

  3. [近日中のタスク] ポートレットにある [John Smith 向け融資] をクリックします。これにより、タスクの詳細、およびユーザ John が使用できる [アクション] オプションが示された [タスクの作業] ページが表示されます (図 7-14 を参照)。
  4. 図 7-14 タスクの詳細情報


    タスクの詳細情報

  5. [アクション] セクションにある [Request Manager Review] を選択して、融資管理者グループに承認の要求を転送し、[次へ] をクリックします。
  6. 更新して表示された Web ページの [キー アクションのプロパティ] に、文字列 Good Guy を入力します。
  7. [送信] をクリックしてタスクを完了します。
  8. 融資は、承認のためにマネージャに送信されたため、John の受信ボックスにはタスク インスタンスが表示されなくなります。
  9. ユーザ John として Worklist User Portal からログアウトします。

割り当てられた融資管理者による融資の拒否

新しいタスク プランのタスク インスタンスを作成する前に、以下の資格を使用して、Loan_Web プロジェクトにログインします

ユーザ名 : Mary

パスワード : password

「John Smith 向け融資」タスクが、Mary の受信ボックスに表示されます。タスクをクリックすると、前に定義したカスタム タスク UI ページ フローが表示されます (図 7-15 を参照)。

図 7-15 [View Asset Summary]

View Asset Summary

  1. 管理者審査ページから、[View Asset Summary] をクリックします。
  2. これにより、図 7-16 に示すように、John Smith の資産が表示されます。

    図 7-16 資産概要

    この表は、John Smith の資産とその実際の価値を (降順に) 示しています。Mary はこの情報を見て、John Smith の資産が 10,000 ドルのみであり、信用度が低い (100) ことが分かります。Mary は、以下の手順を実行して、この融資を拒否することを決定します。

  3. 資産概要ページの [Back] をクリックして、管理者審査フォームに戻ります。
  4. [Reason for Action] に、資産不足および信用度の低さと入力します。
  5. 図 7-17 に示されている [Reject] をクリックすると、マネージャによって融資の申し込みが拒否されます。これにより、タスクが中止状態になり、Mary の [近日中のタスク] ポートレットから削除されます。
  6. 図 7-17 融資の拒否


    融資の拒否


  ページの先頭       前  次