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}