5.Bao基礎編その2
今回は、Baoの各メソッドを実行していって見ましょう。
しかし、実行するためには色々前準備が必要で面倒……。というわけで、幸いBuriのソースコード中にTestが含まれている(testソースフォルダのorg.seasar.buri.bao.test.FurnitureManagementBaoTest2.java)ので、これを元にします。ただ、このままではちょっと説明しづらいので、コピーして書きなおしてみました。
|
まず、このテストケースはS2Unitを利用してます。S2Unitを使っているということは、setUp()でdiconファイルをインクルードさせておくと、フィールド変数にdicon内で定義したコンポーネントが入ってきて、各テストメソッドではそのコンポーネントを利用できる、ということになります。
このソース上では21行目でdiconを読み込んでます。diconの中身はこれ。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components> <include path="bao.dicon"/> <include path="org/seasar/buri/dicon/allTestDao.dicon"/> <component class="org.seasar.buri.bao.FurnitureManagementBao"> <aspect>bao.interceptor</aspect> </component> </components>
FurnitureManagementBaoにbao.interceptorというASPECTが適用されてます。FurnitureManagementBaoは単なるインターフェースなので、このbao.interceptorってのがBaoの全挙動をコントロールしているということに。このbao.interceptorの中身を見たい気もしますが、とりあえずおいといて次へ。
testメソッドであるtestFMBaoTx()では、最初にXPDLを読み込んでいます。これと同等のことは、dicon内で定義することもできて、その場合には、buri2.dicon内のWakanagoFlowsImplコンポーネントのところでこう書いておけばOKです。
<component class="org.seasar.buri.impl.WakanagoFlowsImpl"> <aspect>BuriInterceptorChain</aspect> <initMethod name="readWorkFlowFromResource"> <arg>"資産管理"</arg> <arg>"FurnitureManagement.xpdl"</arg> </initMethod> </component>
ここまでが準備段階、これでBaoを利用できるようになります。
testメソッドでは、まず、FurnitureManagementDtoのインスタンスを生成し、FurnitureManagementBao#enterItemメソッドを呼び出し、そのインスタンスをBaoに渡します。これでワークフローにDtoを登録したことになります。これでフローが開始されます(28〜46行目)。この例では2つのインスタンスを作っていますが、2つの大きな違いは、最初のものは購買備品(AcquisitionTypeBuyをセットしている)で、2つめがリース備品(AquisitionTypeLeaseをセットしている)ってことです。
さて次に、これらがほんとに登録されたのか参照します。これが48〜51行目。ここで実行しているFurnitureManagementBao#getNowUse()メソッドは、メソッド名が「get」で始まっているので、前回見たとおり、データ取得用のメソッドになります。そして、どんなデータを取得するかは、Baoの定数アノテーションを見れば分かります。FurnitureManagementBao内で、
public static String getNowUse_ACTIVITY = "利用中";
このように記述されてますので、これは、「利用中」状態のデータを取得するメソッド、ということが分かります。enterItemメソッドでデータを登録すると、まず「利用中」状態になる、ってことです。
でも、ここでフロー定義を思い出してください(下図参照)。定義上では、「利用中」より前に「備品登録」という状態があります。
この「備品登録」はなぜ飛ばされてしまったのでしょうか?その答えは、「備品登録」と「利用中」の2つのプロパティを見比べてみればわかります。「備品登録」の方は、finish modeがAutomatic、「利用中」の方は、manualと定義されてます。Automaticの場合には、その名の通り自動的に終了し、次の状態に移ってしまうのです。一方manualだと、勝手には終了することはなく、そこで待機することになります。
では、さらにテストメソッドの解説を進めていきます。53〜65行目ではFurnitureManagementBaoのfindNowUseメソッドを実行しています。このメソッドは、「find」で始まってるので、データ取得用メソッドです。ですが、このメソッドはFurnitureManagementDtoを引数にしています。この場合引数のDtoは、取得の条件を表すオブジェクトという意味になります。引数のDtoと同一のプロパティを保持するデータのみを取得します。
53〜58行目の場合、nameプロパティが「T45_002」であるDtoのみ取得しているため、返り値は1件のみ。一方、60〜65行目では、typeプロパティが「PC」であるDtoを取得しようとしており、2つとも返ってきていることを確認しています。
さて次は、この「利用中」の状態から、別の状態に遷移させてみましょう。今回のフローでは「利用中」の次は「期間終了」。この遷移のときに呼びだすメソッドとして、FurnitureManagementBaoではtimeorverItemメソッド(timeoverのスペルミス?)が定義されています。このメソッドを呼び出しているのが、68〜93行目。前半の68〜80行目は、timeorverItemメソッドに、購買備品データのIDを渡して呼び出してます。呼び出した結果、「償却期間終了」状態のデータを取得するgetEndDepreciationメソッドでこの購買備品のデータを取得できるようになり、「利用中」状態のデータを取得するgetNowUseメソッドの返り値には、購買備品データが無くなりました。購買備品が「利用中」状態から「償却期間終了」状態へ遷移したのです。そして同様に、82〜93行目ではリース備品に対してtimeorverItemメソッドを呼んでます。こちらは、「利用中」状態(getNowUseで取得できる状態)から「リース終了」状態(getEndLeaseで取得できる状態)へ遷移しています。
同じメソッドを実行したのになぜ遷移先が変わるのか……。これは、フローの定義を見ていく必要があります。
まず、データ遷移用のメソッド、timeorverItemメソッドが呼ばれたことで、「利用中」状態から「期間終了」状態へ遷移します。そして、この「期間終了」Activityの定義では、Finish modeがAutomatic。だから、自動的に次の状態に移ることになります。だけど、今回の場合は、遷移先が2つに分かれているので、どっちに遷移するのかこれだけでは分かりません。そこで、その条件が定義されている必要があります。この定義に関しては、第三回で纏めてたのですが、再掲します。XPDL内「期間終了」ActivityのPostconditionとして、こんな感じの定義が記述されているのです。
遷移 | 条件 |
---|---|
期間終了→償却期間終了 | #data.isBuying == true |
期間終了→リース終了 | #data.isLease == true |
#dataというのがDtoのインスタンスを示しています。そのインスタンスのisBuyingがtrueなら(購買備品なら)「償却期間終了」Activityへ遷移、isLeaseがtrueなら(リース備品なら)「リース終了」Activityへ遷移する、というのがこの定義の言わんとしているところなのです。
さて、これでFurnitureManagementBaoのメソッドは一通り実行したことに。なんとなく使い方は分かってきたかな……。
要は、Baoの役割は、ワークフロー上のデータを取得するのと、そのデータを遷移させるのと、2つの役割があるよ、ってことっすね。インターフェース定義するだけでこれだけのことが出来るってのは便利便利。
次回は、前回スルーしてたConverterを見てみるかな?、ということで今回はおしまい。