package jp.ne.mki.wedge.rule.client.control;
import java.util.ListIterator;
import java.util.Vector;
import jp.ne.mki.wedge.rule.base.AbstractClient;
import jp.ne.mki.wedge.run.client.control.Manager;
import jp.ne.mki.wedge.run.client.data.Item;
import jp.ne.mki.wedge.run.client.event.ClientToolKit;
import jp.ne.mki.wedge.run.client.event.ExecutionInterface;
import jp.ne.mki.wedge.run.client.event.Judgement;
import jp.ne.mki.wedge.run.client.event.NextExecuteJudger;
import jp.ne.mki.wedge.run.interfaces.DataInterface;
/**
* <h2>Inに設定されたTextアイテムに値が設定されるまでアイテムのAfterイベントを実行する(返り値 引継ぎ)</h2>
* <p>このロジッククラスを実行すると、まず最初に「Inに設定されたTextアイテム」の値が空になります。<br />
* その後は、Out に設定されたアイテムの After 実行リストを順番に実行し、
* ひとつロジッククラスが実行されるタイミングで In アイテムをチェックします。<br />
* この時 In アイテムに何か値が設定されていればを強制的を抜けます<br />
*
* 結果、<code>jp.ne.mki.wedge.rule.client.event.ExecuteAfterTakeOver</code>と似たような動作をしますが、
* 「Inに設定されたTextアイテムに値が設定された」場合は、強制的に SKIP_ALL する点のみが異なります。<br>
* </p>
*
* <br/>
* <h4>[I/O RECORD]</h4>
* <table border="1" cellpadding="3" cellspacing="0" width="100%">
* <tr bgcolor="#EEEEFF" class="TableSubHeadingColor">
* <th style="width:50%;">InputRecord</th>
* <th>OutputRecord</th>
* </tr><tr bgcolor="#EEEEFF" class="TableRowColor">
* <td>
* <!-- InputRecordの内容を記述 -->
* 値が設定されていた場合に実行を終了するためのアイテム。(Text)
* <!-- ここまで -->
* </td>
* <td>
* <!-- OutputRecordの内容を記述 -->
* Afterイベントが設定されているコンポーネント(複数指定可)
* <!-- ここまで -->
* </td>
* </tr></table>
*
* <h4>[RULE PARAMETER]</h4>
* <table border="1" cellpadding="3" cellspacing="0" width="100%">
* <tr>
* <th style="width:100px;" class="TableSubHeadingColor">Parameter</th>
* <td class="TableRowColor">
* <!-- Parameterの内容を記述 -->
* <!--ここまで -->
* </td>
* </tr></table>
*
* @since 1.1.3
* @author mki
* @version 1.0
* @see jp.ne.mki.wedge.rule.client.event.ExecuteAfterTakeOver
* @see jp.ne.mki.wedge.rule.client.control.ExecuteAfterEvent
*/
public class ExecuteAfterUntilEmpty extends AbstractClient {
private DataInterface inItem = null;
private static final int NOT_EMPTY = -1;
/**
* IOパラメータ取得。{@link #execute() execute} の前に実行される。
* @return int OK=処理続行、ERROR=異常終了、CANCEL=処理を中断(正常終了)
*/
public int getIOParameter() {
if (getInRecordCount() < 1) {
return IO_ERROR_IN;
}
inItem = getInRecord(0);
if (inItem.getItemType() != DataInterface.TYPE_TEXT) {
return IO_ERROR_ITEM_TYPE;
}
return OK;
}
/**
* 入力可に変更する処理を実行。OutputRecordに指定されているもの全てを処理する。
* @return int BusinessRuleの戻り値を参照
*/
public int execute() {
// In アイテムを空にする。
inItem.setString("");
int result = OK;
int count = 0;
int size = outputRecord.size();
ListIterator iterator = outputRecord.listIterator();
Item outItem = null;
Vector afterExecutions = null;
try {
while (iterator.hasNext()) {
outItem = (Item) iterator.next();
afterExecutions = outItem.getAfterExecutions();
result = runExecutions(afterExecutions, getManager());
if (result == SKIP || result == SKIP_ALL) {
result = OK;
}
count++;
if (result == NOT_EMPTY) {
result = OK;
break;
}
if (count >= size || result != OK) {
break;
}
}
} finally {
afterExecutions = null;
outItem = null;
iterator = null;
}
return result;
}
/**
* 終了処理。保持していた変数などを開放する処理を記述します。<br/>
* {@link #execute() execute} の後に実行されます。<br/>正常終了・異常終了などに関わらず必ず実行されます。
*/
public void exit() {
inItem = null;
}
/**
* 次の実行リストを実行するかどうかの判断オブジェクト
* Inのアイテムが空で無かった場合にはfalseが返ります。
*
*/
class MyNextExecuteJuder implements NextExecuteJudger {
public Judgement getJudgemenet(int resultCode, ExecutionInterface exec) {
boolean isNextExecute = false;
if (resultCode == OK || resultCode == SKIP) {
if (!"".equals(inItem.getString())) {
// In アイテムが空でなければ break;
resultCode = NOT_EMPTY;
isNextExecute = false;
} else {
isNextExecute = true;
}
}
return new Judgement(isNextExecute, resultCode);
}
}
/**
* 実行リストの処理を実行
* @param executions
* @param manager
* @return
* @throws Throwable
*/
public int runExecutions(Vector executions, final Manager manager) {
return ClientToolKit.runExecutions(executions, manager, new MyNextExecuteJuder());
}
}