    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.fukurou.business;
    017
    018import org.opengion.fukurou.util.ErrorMessage;
    019import org.opengion.fukurou.model.DataModel;                            // 6.7.9.1 (2017/05/19)
    020import org.opengion.fukurou.system.OgRuntimeException ;         // 6.4.2.0 (2016/01/29)
    021
    022/**
    023 * 配列型テーブルモデルをメインカーソルとした業務ロジックの構造を定義します。
    024 *
    025 * 配列型テーブルモデルについては、setTable( ArrayTableModel )によりセットします。
    026 * 配列型テーブルモデルが定義されていない場合、エラーとなります。
    027 *
    028 * このクラスでは、以下に示すメソッドが呼び出されるタイミングのみを定義しています。
    029 * メソッドの中身については、サブクラスでオーバーライドし実装して下さい。
    030 *
    031 * 処理が途中で中断される条件は、以下の3つです。
    032 * ①各メソッドの戻り値がfalseの場合
    033 * ②チェックメソッド(chk***())が全ての行で実行された後、エラーメッセージに"エラー"が含まれている場合
    034 * ③実行時エラーが発生した場合
    035 *
    036 *  fstchk()              変更区分に関わらず   処理を始める前に呼び出し
    037 *  befchk( int row ) 変更区分に関わらず   各行について呼び出し(insert,modify,deleteの前に呼び出し)
    038 *  inschk( int row ) 変更区分が"A"の場合 各行について呼び出し
    039 *  modchk( int row ) 変更区分が"C"の場合 各行について呼び出し
    040 *  delchk( int row ) 変更区分が"D"の場合 各行について呼び出し
    041 *      allchk( int row ) 変更区分に関わらず   各行について呼び出し(insert,modify,deleteの後に呼び出し)
    042 *  first()                       変更区分に関わらず   最初の行でのみ呼び出し
    043 *  befall( int row ) 変更区分に関わらず   各行について呼び出し(insert,modify,deleteの前に呼び出し)
    044 *  insert( int row ) 変更区分が"A"の場合 各行について呼び出し
    045 *  modify( int row ) 変更区分が"C"の場合 各行について呼び出し
    046 *  delete( int row ) 変更区分が"D"の場合 各行について呼び出し
    047 *  allrow( int row ) 変更区分に関わらず   各行について呼び出し(insert,modify,deleteの後に呼び出し)
    048 *  last()            変更区分に関わらず   最後の行でのみ呼び出し
    049 *
    050 * ※ インデックス(row)とは、このArrayTableModel に持つ vals 配列の行のインデックスです。
    051 * よって、オリジナルのDBTableModelの行番号ではありません。
    052 *
    053 * @og.rev 5.1.1.0 (2009/12/01) 新規作成
    054 * @og.group 業務ロジック
    055 *
    056 * @version 5.0
    057 * @author Hiroki Nakamura
    058 * @since JDK1.6,
    059 */
    060public class BizLogic_TABLE extends AbstractBizLogic {
    061        private boolean useLoop = true;                         // 6.8.5.0 (2018/01/09) ループを回すかどうかを引数で指定します。
    062
    063        /**
    064         * デフォルトコンストラクター
    065         *
    066         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    067         */
    068        public BizLogic_TABLE() { super(); }            // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    069
    070        /**
    071         * 処理のメインロジックの前処理を記述します。
    072         * (ここでは何もしません)
    073         *
    074         * このメソッド自体は、protected属性であるため、サブクラスから直接参照することができます。
    075         * 但し、これは、各業務ロジックで直接参照することを想定したものではなく、BizLogicの
    076         * メイン構造を拡張するサブクラスを定義する際に使用することを想定しています。
    077         * (この想定がなければ、本来は、package privateにすべきです)
    078         * このため、業務ロジックを各実装クラスでは直接参照しないで下さい。
    079         */
    080        @Override
    081        protected void init() {
    082                // Document empty method チェック対策
    083        }
    084
    085        /**
    086         * 処理のメインロジックを記述します。
    087         *
    088         * このメソッド自体は、protected属性であるため、サブクラスから直接参照することができます。
    089         * 但し、これは、各業務ロジックで直接参照することを想定したものではなく、BizLogicの
    090         * メイン構造を拡張するサブクラスを定義する際に使用することを想定しています。
    091         * (この想定がなければ、本来は、package privateにすべきです)
    092         * このため、業務ロジックを各実装クラスでは直接参照しないで下さい。
    093         *
    094         * @og.rev 5.1.8.0 (2010/07/01) first,lastは行ループの中で呼び出し
    095         * @og.rev 5.6.7.0 (2013/07/27) Exception を throw するとき、一旦、errMsg 変数にセットします。
    096         * @og.rev 6.7.9.1 (2017/05/19) protected ArrayTableModel を、private DataModel に変更します。
    097         * @og.rev 6.8.5.0 (2018/01/09) first(),last() をループから出して、ループを回すかどうかを引数で指定します。
    098         *
    099         * @return 処理が正常終了したか
    100         */
    101        @Override
    102        protected boolean main() {
    103                final DataModel<String> table = getTable();             // 6.7.9.1 (2017/05/19)
    104
    105                if( table == null ) {
    106                        // 5.6.7.0 (2013/07/27) Exception を throw するとき、一旦、errMsg 変数にセットします。
    107                        final String errMsg = "配列型テーブルモデルがセットされていません。" ;
    108                        throw new OgRuntimeException( errMsg );
    109                }
    110
    111                row = 0;
    112                if( !fstchk() ) { return false; }
    113
    114                final int rowLen = table.getRowCount();                 // 6.8.5.0 (2018/01/09)
    115                if( useLoop ) {                 // 6.8.5.0 (2018/01/09)
    116//      //              for( int i=0; i<table.getRowCount(); i++ ) {
    117                        for( int i=0; i<rowLen; i++ ) {
    118                                if( !befchk( row ) ) { return false; }
    119
    120                                final String modType = table.getModifyType( row );
    121
    122                                // 6.9.7.0 (2018/05/14) PMD These nested if statements could be combined
    123                                if(    "A".equals( modType ) && !inschk( row )
    124                                        || "C".equals( modType ) && !modchk( row )
    125                                        || "D".equals( modType ) && !delchk( row )
    126                                        || !allchk( row ) ) {
    127                                        return false;
    128                                }
    129
    130//                              if( "A".equals( modType ) ) {
    131//                                      if( !inschk( row ) ) { return false; }
    132//                              }
    133//                              else if( "C".equals( modType ) ) {
    134//                                      if( !modchk( row ) ) { return false; }
    135//                              }
    136//                              else if( "D".equals( modType ) ) {
    137//                                      if( !delchk( row ) ) { return false; }
    138//                              }
    139//
    140//                              if( !allchk( row ) ) { return false; }
    141
    142                                row++;
    143                        }
    144                }
    145                if( getKekka() >= ErrorMessage.NG ) { return false; }
    146
    147                row = 0;
    148                if( rowLen > 0 && !first() ) { return false; }          // 6.8.5.0 (2018/01/09) ループの外に出します。
    149
    150                if( useLoop ) {                 // 6.8.5.0 (2018/01/09)
    151//      //              for( int i=0; i<table.getRowCount(); i++ ) {
    152                        for( int i=0; i<rowLen; i++ ) {
    153//      //                      // 5.1.8.0 (2010/07/01) firstは行ループの中で呼び出し
    154//      //                      if( row == 0 ) {
    155//      //                              if( !first() ) { return false; }
    156//      //                      }
    157
    158                                if( !befall( row ) ) { return false; }
    159
    160                                final String modType = table.getModifyType( row );
    161
    162                                // 6.9.7.0 (2018/05/14) PMD These nested if statements could be combined
    163                                if(        "A".equals( modType ) && !insert( row )
    164                                        || "C".equals( modType ) && !modify( row )
    165                                        || "D".equals( modType ) && !delete( row )
    166                                        || !allrow( row ) ) {
    167                                        return false;
    168                                }
    169
    170//                              if( !befall( row ) ) { return false; }
    171//
    172//                              final String modType = table.getModifyType( row );
    173//                              if( "A".equals( modType ) ) {
    174//                                      if( !insert( row ) ) { return false; }
    175//                              }
    176//                              else if( "C".equals( modType ) ) {
    177//                                      if( !modify( row ) ) { return false; }
    178//                              }
    179//                              else if( "D".equals( modType ) ) {
    180//                                      if( !delete( row ) ) { return false; }
    181//                              }
    182//
    183//                              if( !allrow( row ) ) { return false; }
    184//
    185//      //                      // 5.1.8.0 (2010/07/01) lastは行ループの中で呼び出し
    186//      //                      if( row == table.getRowCount() - 1 ) {
    187//      //                              if( !last() ) { return false; }
    188//      //                      }
    189                                row++;
    190                        }
    191                }
    192
    193                if( rowLen > 0 ) {              // 6.8.5.0 (2018/01/09) ループの外に出します。
    194                        row = rowLen-1;
    195                        if( !last() ) { return false; }
    196                }
    197
    198                return true;
    199        }
    200
    201        /**
    202         * このクラスは、テーブルモデルが外部から指定されている必要があります。
    203         *
    204         * このメソッド自体は、protected属性であるため、サブクラスから直接参照することができます。
    205         * 但し、これは、各業務ロジックで直接参照することを想定したものではなく、BizLogicの
    206         * メイン構造を拡張するサブクラスを定義する際に使用することを想定しています。
    207         * (この想定がなければ、本来は、package privateにすべきです)
    208         * このため、業務ロジックを各実装クラスでは直接参照しないで下さい。
    209         *
    210         * @see AbstractBizLogic#isRequireTable()
    211         *
    212         * @return テーブルモデルが外部から指定されている必要があるかどうか(常にtrue)
    213         */
    214        @Override
    215        protected boolean isRequireTable() {
    216                return true;
    217        }
    218
    219        /**
    220         * メインカーソルの一番初めで呼ばれるチェックロジックを定義します。
    221         * ここでは何も実装されていません。
    222         *
    223         * @return 処理が正常終了したか
    224         */
    225        protected boolean fstchk() {
    226                return true;
    227        }
    228
    229        /**
    230         * メインカーソルの各行(変更区分の各処理の前)で呼ばれるチェックロジックを定義します。
    231         * ここでは何も実装されていません。
    232         *
    233         * @param row 行番号(インデックス)
    234         *
    235         * @return 処理が正常終了したか
    236         */
    237        protected boolean befchk( final int row ) {
    238                return true;
    239        }
    240
    241        /**
    242         * メインカーソルの各行(変更区分の各処理の後)で呼ばれるチェックロジックを定義します。
    243         * ここでは何も実装されていません。
    244         *
    245         * @param row 行番号(インデックス)
    246         *
    247         * @return 処理が正常終了したか
    248         */
    249        protected boolean allchk( final int row ) {
    250                return true;
    251        }
    252
    253        /**
    254         * メインカーソルの各行(変更区分="A")で呼ばれるチェックロジックを定義します。
    255         * ここでは何も実装されていません。
    256         *
    257         * @param row 行番号(インデックス)
    258         *
    259         * @return 処理が正常終了したか
    260         */
    261        protected boolean inschk( final int row ) {
    262                return true;
    263        }
    264
    265        /**
    266         * メインカーソルの各行(変更区分="C")で呼ばれるチェックロジックを定義します。
    267         * ここでは何も実装されていません。
    268         *
    269         * @param row 行番号(インデックス)
    270         *
    271         * @return 処理が正常終了したか
    272         */
    273        protected boolean modchk( final int row ) {
    274                return true;
    275        }
    276
    277        /**
    278         * メインカーソルの各行(変更区分="D")で呼ばれるチェックロジックを定義します。
    279         * ここでは何も実装されていません。
    280         *
    281         * @param row 行番号(インデックス)
    282         *
    283         * @return 処理が正常終了したか
    284         */
    285        protected boolean delchk( final int row ) {
    286                return true;
    287        }
    288
    289        /**
    290         * メインカーソルの一番初めで呼ばれるロジックを定義します。
    291         * ここでは何も実装されていません。
    292         *
    293         * @return 処理が正常終了したか
    294         */
    295        protected boolean first() {
    296                return true;
    297        }
    298
    299        /**
    300         * メインカーソルの一番最後で呼ばれるロジックを定義します。
    301         * ここでは何も実装されていません。
    302         *
    303         * @return 処理が正常終了したか
    304         */
    305        protected boolean last() {
    306                return true;
    307        }
    308
    309        /**
    310         * メインカーソルの各行(変更区分の各処理の前)で呼ばれるロジックを定義します。
    311         * ここでは何も実装されていません。
    312         *
    313         * @param row 行番号(インデックス)
    314         *
    315         * @return 処理が正常終了したか
    316         */
    317        protected boolean befall( final int row ) {
    318                return true;
    319        }
    320
    321        /**
    322         * メインカーソルの各行(変更区分の各処理の後)で呼ばれるロジックを定義します。
    323         * ここでは何も実装されていません。
    324         *
    325         * @param row 行番号(インデックス)
    326         *
    327         * @return 処理が正常終了したか
    328         */
    329        protected boolean allrow( final int row ) {
    330                return true;
    331        }
    332
    333        /**
    334         * メインカーソルの各行(変更区分="A")で呼ばれるロジックを定義します。
    335         * ここでは何も実装されていません。
    336         *
    337         * @param row 行番号(インデックス)
    338         *
    339         * @return 処理が正常終了したか
    340         */
    341        protected boolean insert( final int row ) {
    342                return true;
    343        }
    344
    345        /**
    346         * メインカーソルの各行(変更区分="C")で呼ばれるロジックを定義します。
    347         * ここでは何も実装されていません。
    348         *
    349         * @param row 行番号(インデックス)
    350         *
    351         * @return 処理が正常終了したか
    352         */
    353        protected boolean modify( final int row ) {
    354                return true;
    355        }
    356
    357        /**
    358         * メインカーソルの各行(変更区分="D")で呼ばれるロジックを定義します。
    359         * ここでは何も実装されていません。
    360         *
    361         * @param row 行番号(インデックス)
    362         *
    363         * @return 処理が正常終了したか
    364         */
    365        protected boolean delete( final int row ) {
    366                return true;
    367        }
    368
    369        /**
    370         * ループを回すかどうかを指定します。
    371         *
    372         * ループ処理を使用しない場合の処理速度向上のためのフラグです。
    373         *
    374         * ループ処理とは、引数に row番号を指定する関数です。
    375         * 初期値は、true(ループを回す) です。
    376         * false を指定すると、それらのメソッドは使用されず、fstchk()、first()、last() のみ呼び出されます。
    377         *
    378         * init() と main() は、AbstractBizLogic#exec() から呼ばれるため、通常通り呼び出されます。
    379         *
    380         * @og.rev 6.8.5.0 (2018/01/09) ループを回すかどうかを引数で指定します。
    381         *
    382         * @param useLoop ループを回すかどうか
    383         */
    384        protected final void setUseLoop( final boolean useLoop ) {
    385                this.useLoop = useLoop;
    386        }
    387}