package jp.ne.mki.wedge.rule.client.control;
import java.util.Vector;
import java.util.logging.Level;
import jp.ne.mki.wedge.rule.base.AbstractClient;
import jp.ne.mki.wedge.run.client.data.Item;
import jp.ne.mki.wedge.run.client.executer.ExecutionExecuter;
/**
* <h2>IfElse構造化ロジッククラス</h2>
* <p>
* 入力引数のアイテムAfterを 条件、出力引数のアイテムAfter を処理 として IfElse の構造化を行います。<br>
* 入力引数のアイテムAfterを実行し、戻り値にOKが返って来た場合のみ 出力引数の同行アイテムAfterを実行し
* 処理を終了します。<br>
* 入力引数のアイテムAfterの結果がいずれもOKで返らなかった場合には、入力引数の数 + 1個目の 行である
* 出力引数のアイテムのAfterを実行します。(else としての処理)
* </p>
* <p>
* <table border="1">
* <tr><th>入力引数</th><th>出力引数</th></tr>
* <tr><td>アイテムA</td><td>アイテムD</td></tr>
* <tr><td>アイテムB</td><td>アイテムE</td></tr>
* <tr><td>アイテムC</td><td>アイテムF</td></tr>
* <tr><td></td><td>アイテムG</td></tr>
* <table>
* <br>
* という設定がされた場合には、以下のような処理になります。<br>
* <br>
* <pre>
* if( アイテムA:After == OK ){
* return アイテムD:After;
* }
* else if( アイテムB:After == OK ){
* return アイテムE:After;
* }
* else if( アイテムC:After == OK ){
* return アイテムF:After;
* }
* else{
* return アイテムG:After;
* }
* </pre>
* 入力引数のアイテムAfterは、「条件式」として扱い、戻り値は 基本的に OK か それ以外か の
* 判断で行います。<br>
* 「条件式」での戻り値では、 OK 、 CANCEL(もしくは ERROR) のいずれかを返すように
* して、
* STOP,STOP_SELECT_ALL,FRAME_CLOSE などの 戻り値は使用しないようにして下さい。 <br>
* 「条件式」にて、最後の戻り値が SKIP,SKIP_ALL などの場合は OK とみなされます。<br>
*
*
* <br>
* このロジッククラスの戻り値は、
* 以下の仕様に基づき変換され このロジッククラスの戻り値として返します。<br>
* <br>
* <table border="1">
* <tr><th>出力アイテムAfterの戻り値</th><th>次の出力アイテム実行有無</th><th>このロジッククラスの戻り値</th></tr>
* <tr><td>OK</td><td>○</td><td>OK</td></tr>
* <tr><td>ERROR</td><td>×</td><td>ERROR</td></tr>
* <tr><td>STOP</td><td>×</td><td>STOP</td></tr>
* <tr><td>CANCEL</td><td>×</td><td>CANCEL</td></tr>
* <tr><td>SKIP</td><td>○</td><td>OK</td></tr>
* <tr><td>SKIP_ALL</td><td>○</td><td>OK</td></tr>
* <tr><td>FRAME_CLOSE</td><td>×</td><td>SKIP_ALL</td></tr>
* <tr><td>FRAME_QUIT</td><td>×</td><td>SKIP_ALL</td></tr>
* <tr><td>SYSTEM_EXIT</td><td>×</td><td>SKIP_ALL</td></tr>
* <tr><td>SYSTEM_QUIT</td><td>×</td><td>SKIP_ALL</td></tr>
* <table>
* </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の内容を記述 -->
* <ol><li>ケースロジックアイテム(複数)</li></ol>
* <!-- ここまで -->
* </td>
* <td>
* <!-- OutputRecordの内容を記述 -->
* <ol><li>処理ロジックアイテム(複数) <br> 但し、In引数の数 + 1 設定する必要がある</li></ol>
* <!-- ここまで -->
* </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>
*
* @author mki
* @version 1.0
*/
public class StructureIfElse extends AbstractClient {
/**
* 入力アイテムに設定があれば、エラー処理があると認識する
* IOパラメータ取得。{@link #execute() execute} の前に実行される。
*
* @return int int OK=処理続行、ERROR=異常終了、CANCEL=処理を中断(正常終了)
*/
public int getIOParameter() throws Throwable {
if (getInRecordCount() == (getOutRecordCount() + 1)) {
errorMessage = "出力引数の数は 入力引数+1 でなければいけません。";
return IO_ERROR;
}
return OK;
}
/**
* 出力アイテムのAfter処理を順次実行する
* 各Afterの戻り値が OK 出ない場合には処理中断し実行リストに処理を戻す。
* 但し、SKIP or SKIP_ALL の場合には OK とみなし処理続行する。
*
* @return int BusinessRuleの戻り値を参照
*/
public int execute() throws Throwable {
log(Level.FINER, "- If Else start - " + getLogicalName(), null);
int result = OK;
int size = getInRecordCount();
for (int i = 0; i < size; i++) {
result = changeReturn(executeItemAfterExecution(getInItem(i), i));
//条件に当てはまったとき
if (result == OK) {
log(
Level.FINER,
" -- case MATCH → case:"
+ getInItem(i).getLogicalName()
+ ", execute:"
+ getOutItem(i).getLogicalName(), null);
return changeReturn(executeItemAfterExecution(getOutItem(i), i));
}
}
//どの条件に当てはまらなかったとき
log(Level.FINER, " -- Case NO Match → execute : " + getOutItem(size).getLogicalName(), null);
return changeReturn(executeItemAfterExecution(getOutItem((size)), (size)));
}
/**
* 出力アイテムのAfterを実行
*/
protected int executeItemAfterExecution(Item item, int index) {
Vector executions = item.getAfterExecutions();
return ExecutionExecuter.runExecutions(executions, getManager());
}
/**
* 入力アイテムのAfterの戻り値を、このロジッククラスの戻り値に変換
*
* @param result
* @return
*/
protected int changeReturn(int result) {
// SKIP , SKIP_ALL の場合には OKを戻り値に返す
if (result == SKIP || result == SKIP_ALL) {
return OK;
}
// 処理内にて画面終了 もしくは システム終了された場合には以降の処理は中断
// 終了処理自体は既に終了しているため、SKIP_ALL 返す
else if (result == FRAME_CLOSE || result == FRAME_QUIT || result == SYSTEM_EXIT || result == SYSTEM_QUIT) {
return SKIP_ALL;
} else {
return result;
}
}
/**
* 終了処理。保持していた変数などを開放する処理を記述します。<br/>
* {@link #execute() execute} の後に実行されます。<br/>正常終了・異常終了などに関わらず必ず実行されます。
*/
public void exit() throws Throwable {
}
}