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.hayabusa.db;
017
018import java.util.concurrent.ConcurrentMap;                                                      // 6.4.3.3 (2016/03/04)
019import java.util.concurrent.ConcurrentHashMap;                                          // 6.4.3.1 (2016/02/12) refactoring
020import java.util.Set;                                                                                           // 6.0.2.4 (2014/10/17)
021import java.util.HashSet;                                                                                       // 6.0.2.4 (2014/10/17)
022import java.util.Arrays;                                                                                        // 8.5.4.2 (2024/01/12) PMD 7.0.0 UseArraysAsList 対応
023import java.util.function.BiConsumer;                                                           // 6.4.5.0 (2016/04/08)
024import java.util.regex.Pattern;
025
026import org.opengion.fukurou.util.StringUtil;
027import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;      // 6.1.0.0 (2014/12/26) refactoring
028
029/**
030 * 編集設定情報を管理するためのデータ管理クラスです。
031 * ここで管理される各パラメーターの意味は以下の通りです。
032 * (各インデックス番号は、内部的に管理されているインデックス番号を意味します)
033 *
034 * ・0:編集名
035 *       この編集設定オブジェクトの名称です。
036 * ・1:表示カラム
037 *       表示対象となるカラム一覧です。CSV形式で指定します。
038 *       この一覧には、非表示のカラムも合わせて管理され、非表示カラムについては、
039 *       カラム名の先頭に"!"をつけます。
040 *       例) AAA,!BBB,CCC ⇒ AAA,CCCの順に表示(BBBは非表示)
041 * ・2:集計カラム
042 *       各値をSUMする対象となるカラムです。(CSV形式で複数指定が可能)
043 *       ここで指定されたカラムは数値型である必要があります。
044 *       SQL構文における、SUM関数の引数として指定するカラムに相当します。
045 * ・3:グループカラム
046 *       集計カラムの各値をグルーピングするためのカラムです。(CSV形式で複数指定が可能)
047 *       SQL構文における、GROUP BYに指定するカラムに相当します。
048 * ・4:小計カラム
049 *       集計カラムの各値に対し、小計行を付加するためのブレイクキーを指定します。(CSV形式で複数指定が可能)
050 * ・5:合計カラム
051 *       集計カラムの各値に対し、合計行を付加するためのブレイクキーを指定します。(CSV形式で複数指定が可能)
052 * ・6:総合計フラグ
053 *       集計カラムの各値に対し、総合計行を付加するかどうかを指定します。(0以外:追加する 0:追加しない)
054 * ・7:表示順カラム
055 *       データの表示順をその順番にCSV形式で指定します。
056 *       カラム名の先頭に"!"をつけた場合は、そのカラムは降順で表示されます。
057 *       SQL構文における、orderby句に相当します。
058 * ・8:共通フラグ
059 *       この編集設定オブジェクトが、共通(全ユーザー公開)編集かどうかを
060 *       指定します。(0以外:共通 0:個人のみ)
061 *
062 * @og.rev 5.3.6.0 (2011/06/01) 新規追加
063 *
064 * @version  5.0
065 * @author   Hiroki Nakamura
066 * @since    JDK6.0,
067 */
068public class DBEditConfig {
069
070        private static final int EDIT_KEY_NAME          = 0;
071        private static final int EDIT_KEY_VIEW          = 1;
072        private static final int EDIT_KEY_SUM           = 2;
073        private static final int EDIT_KEY_GROUP         = 3;
074        private static final int EDIT_KEY_SUBTOTAL      = 4;
075        private static final int EDIT_KEY_TOTAL         = 5;
076        private static final int EDIT_KEY_GRANDTOTAL= 6;
077        private static final int EDIT_KEY_FIRSTTOTAL= 7;                // 6.1.1.0 (2015/01/17) FIRSTTOTAL 追加
078        private static final int EDIT_KEY_ORDERBY       = 8;
079        private static final int EDIT_KEY_COMMON        = 9;
080
081        private static final String[] EDIT_KEYS                 // 6.3.9.1 (2015/11/27) 修飾子を、なし → private に変更。キーに、"EDIT_" を最初から付けておきます。
082                = { "EDIT_NAME", "EDIT_VIEW", "EDIT_SUM", "EDIT_GROUP", "EDIT_SUBTOTAL", "EDIT_TOTAL", "EDIT_GRANDTOTAL", "EDIT_FIRSTTOTAL", "EDIT_ORDERBY", "EDIT_COMMON" };
083
084        private final String[] editVals = new String[EDIT_KEYS.length];         // 6.3.9.1 (2015/11/27) 再利用率が低いのと、コンパイラが何とかしてくれるでしょう。
085
086        private int sumClmCount;
087        private int groupClmCount;
088        private int subTotalClmCount;
089        private int totalClmCount;
090        /** 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 */
091        private final ConcurrentMap<String,String> orderMap = new ConcurrentHashMap<>();
092        private String orderByDescClms;
093
094        /**
095         * コンストラクタ
096         *
097         * 空の編集設定オブジェクトを構築します。
098         */
099        public DBEditConfig() { super(); }              // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
100
101        /**
102         * コンストラクタ
103         *
104         * 各種パラメーターを指定して編集設定オブジェクトを構築します。
105         *
106         * @og.rev 6.1.1.0 (2015/01/17) 総合計を最初の行に追加するかどうか(FirstTotal)の属性を追加
107         *
108         * @param editName 編集名称
109         * @param viewClms 画面表示カラム
110         * @param sumClms 集計カラム
111         * @param groupClms グループカラム
112         * @param subTotalClms 小計カラム
113         * @param totalClms 合計カラム
114         * @param useGrandTotal 総合計行を追加するか(1:追加する 1以外:追加しない)
115         * @param useFirstTotal 総合計行を追加するか(1:追加する 1以外:追加しない)
116         * @param orderByClms 表示順
117         * @param isCommon 共通編集かどうか(1:共通 1以外:個人のみ)
118         */
119        public DBEditConfig( final String editName, final String viewClms
120                                                , final String sumClms, final String groupClms
121                                                , final String subTotalClms, final String totalClms
122                                                , final String useGrandTotal, final String useFirstTotal
123                                                , final String orderByClms, final String isCommon ) {
124
125                editVals[EDIT_KEY_NAME]                 = editName;
126                editVals[EDIT_KEY_VIEW]                 = viewClms;
127                editVals[EDIT_KEY_SUM]                  = sumClms;
128                editVals[EDIT_KEY_GROUP]                = groupClms;
129                editVals[EDIT_KEY_SUBTOTAL]             = subTotalClms;
130                editVals[EDIT_KEY_TOTAL]                = totalClms;
131                editVals[EDIT_KEY_GRANDTOTAL]   = useGrandTotal;
132                editVals[EDIT_KEY_FIRSTTOTAL]   = useFirstTotal;        // 6.1.1.0 (2015/01/17)
133                editVals[EDIT_KEY_ORDERBY]              = orderByClms;
134                editVals[EDIT_KEY_COMMON]               = isCommon;
135
136                init();
137        }
138
139        /**
140         * コンストラクタ
141         *
142         * 各種パラメーターを配列で指定して編集設定オブジェクトを構築します。
143         * 各パラメータの配列インデックスは、{@link #getEditKeys(String,String)}で返される
144         * キー一覧の配列インデックスと一致します。
145         * 各パラメーターの意味については、クラスのJavadoc{@link DBEditConfig}を参照して下さい。
146         *
147         * @param editVals 設定値(配列)
148         */
149        public DBEditConfig( final String[] editVals ) {
150                System.arraycopy( editVals, 0, this.editVals, 0, editVals.length );
151                init();
152        }
153
154        /**
155         * 編集設定オブジェクト作成時の初期化処理です。
156         * コンストラクタの引数に基づき内部変数の初期設定を行います。
157         */
158        private void init() {
159                sumClmCount             = StringUtil.csv2Array( editVals[EDIT_KEY_SUM]          ).length;
160                groupClmCount   = StringUtil.csv2Array( editVals[EDIT_KEY_GROUP]        ).length;
161                subTotalClmCount= StringUtil.csv2Array( editVals[EDIT_KEY_SUBTOTAL]     ).length;
162                totalClmCount   = StringUtil.csv2Array( editVals[EDIT_KEY_TOTAL]        ).length;
163
164                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
165                if( editVals[EDIT_KEY_ORDERBY] == null ) {
166                        orderByDescClms = null;
167                }
168                else {
169                        final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
170                        final String[] ary = StringUtil.csv2Array( editVals[EDIT_KEY_ORDERBY] );
171                        for( int i=0; i<ary.length ;i++ ) {
172                                String str = ary[i];
173                                if( StringUtil.startsChar( str , '!' ) ) {                              // 6.2.0.0 (2015/02/27) 1文字 String.startsWith
174                                        str = str.substring( 1 );
175                                        if( buf.length() > 0 ) { buf.append( ',' ); }           // 6.0.2.5 (2014/10/31) char を append する。
176                                        buf.append( str );
177                                }
178                                orderMap.put( str, String.valueOf( i+1 ) );
179                        }
180                        orderByDescClms = buf.toString();
181                }
182        }
183
184        /**
185         * 画面ID、編集名をキーに、編集設定オブジェクトの各設定値の管理キーを指定します。
186         *
187         * 編集設定オブジェクトで管理される各キーに対して、
188         * "EDIT_[KEY]_(画面ID)_(編集名)"というキーを生成し、これを配列にして返します。
189         *
190         * @og.rev 6.0.2.2 (2014/10/03) 新規追加。DBEditConfig から、移動
191         * @og.rev 6.3.9.1 (2015/11/27) DBEditConfigManager から、移動。
192         *
193         * @param guikey 画面ID
194         * @param editName 編集名
195         *
196         * @return 編集設定を管理するためのキー一覧
197         */
198        public static String[] getEditKeys( final String guikey, final String editName ) {
199                final String[] rtn = new String[EDIT_KEYS.length];
200                final String keyNm = "_" + guikey + "_" + editName;
201
202                for( int i=0; i<EDIT_KEYS.length; i++ ) {
203                        rtn[i] = EDIT_KEYS[i] + keyNm;
204                }
205                return rtn;
206        }
207
208        /**
209         * 編集設定オブジェクトの各設定値を配列にして返します。
210         *
211         * 配列のインデックス番号は、{@link #getEditKeys(String,String)}で生成されるキーの
212         * インデックス番号と一致します。
213         *
214         * @return 編集設定オブジェクトの設定値一覧(配列)
215         */
216        public String[] getEditVals() {
217                final String[] rtn = new String[editVals.length];
218                System.arraycopy( editVals, 0, rtn, 0, editVals.length );
219                return rtn;
220        }
221
222        /**
223         * 編集名を返します。
224         *
225         * @return 編集名
226         */
227        public String getEditName() {
228                return editVals[EDIT_KEY_NAME];
229        }
230
231        /**
232         * 書き込み許可するかどうかを決める為の情報を返します。
233         *
234         * EDITNAME利用時は、writeCheckタグ内で書き込み許可判定を行っています。(ROLE制御は別)
235         * USE_EDIT_WITH_EDITNAME か、writeCheckタグのuseEditをtrueにすれば、書き込み許可となり
236         * USE_EDIT_WITH_NAME_SEQ が true の場合は、このメソッドの戻り値がtrue なら書き込み許可となります。
237         *
238         * 成立条件:
239         *   EDIT_KEY_NAME に、非表示(!カラム)がなく、集計カラム,グループカラム,小計カラム,合計カラム,総合計行 も
240         *   未使用の場合は、true を、それ以外は、false を返します。
241         *   要するに、列の並び替えと、表示順、(降順)指定のみの場合だけ、書き込み許可します。
242         *
243         * @og.rev 7.2.9.1 (2020/10/23) writeCheckタグ内で書き込み許可するかどうかを決める為の情報
244         *
245         * @return 編集名
246         */
247        public boolean useEditName() {
248                return editVals[EDIT_KEY_VIEW] != null && editVals[EDIT_KEY_VIEW].indexOf( '!' ) < 0 &&
249                                !useSum() && !useGroup() && !useSubTotal() && !useTotal() && !useGrandTotal() ;
250        }
251
252        /**
253         * 表示カラム名の一覧をCSV形式で返します。
254         * 非表示カラムについては、カラム名の先頭に"!"をつけて返されます。
255         * 例) AAA,!BBB,CCC ⇒ AAA,CCCの順に表示(BBBは非表示)
256         *
257         * @return 表示カラム名一覧(CSV形式)
258         */
259        public String getViewClms() {
260                return editVals[EDIT_KEY_VIEW];
261        }
262
263        /**
264         * 表示カラム(CSV形式)をチェックし、変更があれば、反映したカラムを作成します。
265         *
266         * 表示カラムは、並び順や非表示マーカー(!)などが加味され、ユーザー、画面ごとに
267         * データベースに記録されています。JSPソースを修正した場合、データベースに
268         * 書き込まれた表示カラムは、反映されないため、カラム選択画面等に表示されません。
269         * そこで、オリジナルのカラムに追加された場合は、カラムを比較することで、
270         * 追加分のカラムを、非表示カラムとして、後ろに追記します。
271         * 削除された場合は、ViewForm で警告表示することで、ユーザーに変更を促します。
272         *
273         * @og.rev 6.0.2.4 (2014/10/17) JSP修正時の追加カラム対応
274         * @og.rev 5.9.32.0 (2018/05/02) spritView使用時の対応
275         *
276         * @param       orgClms         オリジナルのカラム(CSV形式)
277         *
278         * @return      変更後の表示カラム(CSV形式)
279         */
280        public String getViewClms( final String orgClms ) {
281                String viewClms = editVals[EDIT_KEY_VIEW];
282
283                if( orgClms == null || orgClms.isEmpty() ) { return viewClms; }         // orgClms がなければ、viewClms を返す。
284                // 基本的には、両者のカラムは、一致するはず。
285//              final String[] vclms = viewClms.split( "," );           // 表示順、非表示処理を行ったカラム
286                final Pattern pattern1 = Pattern.compile("[,|]");       // spritView使用を考慮して、「 , or | 」で分割します。 5.9.32.0 ADD
287                final String[] vclms = pattern1.split(viewClms);
288//              final String[] fclms = orgClms.split( "," );            // 元々の表示可能カラムすべて(fullClms)
289                final String[] fclms = vclms.clone();                                           // spritView使用時は未固定の列情報のみ渡されるため、vclmsの値から取得するように変更。5.9.32.0 ADD
290                for(int i=0; i<fclms.length; i++) {
291                        fclms[i] = fclms[i].charAt(0) == '!' ? fclms[i].substring(1) : fclms[i]; // 非表示の(!)は削除します。
292                }
293
294                // 表示可能カラムすべての Set を作成します。
295                final Set<String> fset = new HashSet<>();
296                // 8.5.4.2 (2024/01/12) PMD 7.0.0 ForLoopCanBeForeach
297                // 8.5.4.2 (2024/01/12) PMD 7.0.0 UseArraysAsList 対応
298//              for( int i=0; i<fclms.length; i++ ) {           // orgClms をSet に追加します。
299//                      fset.add( fclms[i] );
300//              }
301                fset.addAll( Arrays.asList( fclms ) );          // orgClms をSet に追加します。
302
303                // 非表示カラムの内、表示可能カラムに存在しない分だけの Set を作成します。
304                // また、表示可能カラムから、順番に、viewClms の値を削除していきます。
305                final Set<String>   vset = new HashSet<>();
306                final StringBuilder vbuf = new StringBuilder( BUFFER_MIDDLE );  // 新しい viewClms 作成用
307                // 8.5.4.2 (2024/01/12) PMD 7.0.0 ForLoopCanBeForeach
308//              for( int i=0; i<vclms.length; i++ ) {           // viewClms をSet に追加します。
309//                      String clm = vclms[i];
310                for( final String vclm : vclms ) {                      // viewClms をSet に追加します。
311                        String clm = vclm;
312                        if( clm == null || clm.isEmpty() ) { continue; }                        // 6.0.2.5 (2014/10/31) 潜在バグ? 先頭に"," が来るとアベンドする。
313                        clm = clm.charAt(0) == '!' ? clm.substring(1) : clm ;           // 非表示の (!) は削除します。
314                        if( fset.remove( clm ) ) {                              // fullSet にあれば、削除するとともに、新viewClmsを作成する。
315                                if( vbuf.length() > 0 ) { vbuf.append(','); }                   // 最初以降は、カンマで連結する。              // 6.0.2.5 (2014/10/31) char を append する。
316//                              vbuf.append( vclms[i] );                        // append するのは、(!) 付のカラム
317                                vbuf.append( vclm );                            // append するのは、(!) 付のカラム(つまりfor変数の引数)
318                        }
319                        else {
320                                vset.add( clm );                                        // fullSet になければ、viewSet に追加
321                        }
322                }
323
324                // この段階で、fset、vset ともに、それぞれ独自のカラムが残っている。
325                // どちらも、残っていなければ、正常なので、viewClms を返す。
326                if( vset.isEmpty() && fset.isEmpty() ) { return viewClms; }
327
328                // fullSet にカラムが残っていれば、非表示で、新viewClmsに、追加する。
329                if( !fset.isEmpty() ) {
330//                      final String[] defClms = fset.toArray( new String[fset.size()] );
331                        // 8.5.4.2 (2024/01/12) PMD 7.0.0 ForLoopCanBeForeach
332//                      final String[] defClms = fset.toArray( new String[0] ); // 8.5.4.2 (2024/01/12) PMD 7.0.0 OptimizableToArrayCall 対応
333//                      for( int i=0; i<defClms.length; i++ ) {
334//                              if( vbuf.length() > 0 ) { vbuf.append(','); }   // 6.0.2.5 (2014/10/31) 最初以降は、カンマで連結する。
335//                              vbuf.append('!').append( defClms[i] );                  // 非表示カラムとして、後ろに追加する。
336//                      }
337                        for( final String defClm : fset ) {
338                                if( vbuf.length() > 0 ) { vbuf.append(','); }   // 6.0.2.5 (2014/10/31) 最初以降は、カンマで連結する。
339                                vbuf.append('!').append( defClm );                              // 非表示カラムとして、後ろに追加する。
340                        }
341                }
342                viewClms = vbuf.toString();
343                editVals[EDIT_KEY_VIEW] = viewClms;
344
345                return viewClms;
346        }
347
348        /**
349         * 集計カラムの一覧をCSV形式で返します。
350         *
351         * @return 集計カラムの一覧(CSV形式)
352         */
353        public String getSumClms() {
354                return editVals[EDIT_KEY_SUM];
355        }
356
357        /**
358         * 集計処理を行うかどうかを返します。
359         * これは、集計カラムが指定されているか、と同じ意味です。
360         *
361         * @return true:対象 false:非対象
362         */
363        public boolean useSum() {
364                return editVals[EDIT_KEY_SUM] != null && editVals[EDIT_KEY_SUM].length() > 0 ;
365        }
366
367        /**
368         * 指定されたカラムが集計対象のカラムかどうかを返します。
369         *
370         * @param clm カラム
371         *
372         * @return true:対象 false:非対象
373         */
374        public boolean isSumClm( final String clm ) {
375                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
376                // 条件反転注意
377                return clm != null && editVals[EDIT_KEY_SUM] != null && ( ","+editVals[EDIT_KEY_SUM]+"," ).indexOf( ","+clm+"," ) >= 0 ;
378        }
379
380        /**
381         * 集計カラムのカラム数を返します。
382         *
383         * @return 集計カラムのカラム数
384         */
385        public int getSumClmCount() {
386                return sumClmCount;
387        }
388
389        /**
390         * グループカラムの一覧をCSV形式で返します。
391         *
392         * @return グループカラムの一覧(CSV形式)
393         */
394        public String getGroupClms() {
395                return editVals[EDIT_KEY_GROUP];
396        }
397
398        /**
399         * グループ処理を行うかどうかを返します。
400         * これは、グループカラムが指定されているか、と同じ意味です。
401         *
402         * @return true:対象 false:非対象
403         */
404        public boolean useGroup() {
405                return editVals[EDIT_KEY_GROUP] != null && editVals[EDIT_KEY_GROUP].length() > 0 ;
406        }
407
408        /**
409         * 指定されたカラムがグループ対象のカラムかどうかを返します。
410         *
411         * @param clm カラム
412         *
413         * @return true:対象 false:非対象
414         */
415        public boolean isGroupClm( final String clm ) {
416                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
417                // 条件反転注意
418                return clm != null && editVals[EDIT_KEY_GROUP] != null && ( ","+editVals[EDIT_KEY_GROUP]+"," ).indexOf( ","+clm+"," ) >= 0 ;
419        }
420
421        /**
422         * グループカラムのカラム数を返します。
423         *
424         * @return グループカラムのカラム数
425         */
426        public int getGroupClmCount() {
427                return groupClmCount;
428        }
429
430        /**
431         * 小計カラムの一覧をCSV形式で返します。
432         *
433         * @return 小計カラムの一覧(CSV形式)
434         */
435        public String getSubTotalClms() {
436                return editVals[EDIT_KEY_SUBTOTAL];
437        }
438
439        /**
440         * 小計処理を行うかどうかを返します。
441         * これは、小計カラムが指定されているか、と同じ意味です。
442         *
443         * @return true:対象 false:非対象
444         */
445        public boolean useSubTotal() {
446                return editVals[EDIT_KEY_SUBTOTAL] != null && editVals[EDIT_KEY_SUBTOTAL].length() > 0 ;
447        }
448
449        /**
450         * 指定されたカラムが小計対象のカラムかどうかを返します。
451         *
452         * @param clm カラム
453         *
454         * @return true:対象 false:非対象
455         */
456        public boolean isSubTotalClm( final String clm ) {
457                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
458                // 条件反転注意
459                return clm != null && editVals[EDIT_KEY_SUBTOTAL] != null && ( ","+editVals[EDIT_KEY_SUBTOTAL]+"," ).indexOf( ","+clm+"," ) >= 0 ;
460        }
461
462        /**
463         * 小計カラムのカラム数を返します。
464         *
465         * @return グループカラムのカラム数
466         */
467        public int getSubTotalClmCount() {
468                return subTotalClmCount;
469        }
470
471        /**
472         * 合計カラムの一覧をCSV形式で返します。
473         *
474         * @return 合計カラムの一覧(CSV形式)
475         */
476        public String getTotalClms() {
477                return editVals[EDIT_KEY_TOTAL];
478        }
479
480        /**
481         * 合計処理を行うかどうかを返します。
482         * これは、合計カラムが指定されているか、と同じ意味です。
483         *
484         * @return true:対象 false:非対象
485         */
486        public boolean useTotal() {
487                return editVals[EDIT_KEY_TOTAL] != null && editVals[EDIT_KEY_TOTAL].length() > 0 ;
488        }
489
490        /**
491         * 指定されたカラムが合計対象のカラムかどうかを返します。
492         *
493         * @param clm カラム
494         *
495         * @return true:対象 false:非対象
496         */
497        public boolean isTotalClm( final String clm ) {
498                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
499                // 条件反転注意
500                return clm != null && editVals[EDIT_KEY_TOTAL] != null && ( ","+editVals[EDIT_KEY_TOTAL]+"," ).indexOf( ","+clm+"," ) >= 0 ;
501        }
502
503        /**
504         * 合計カラムのカラム数を返します。
505         *
506         * @return グループカラムのカラム数
507         */
508        public int getTotalClmCount() {
509                return totalClmCount;
510        }
511
512        /**
513         * 総合計行を付加するかどうかを返します。
514         *
515         * @return true:対象 false:非対象
516         */
517        public boolean useGrandTotal() {
518                return StringUtil.nval( editVals[EDIT_KEY_GRANDTOTAL], false );
519        }
520
521        /**
522         * 総合計を最初の行に追加するかどうかを返します。
523         *
524         * @og.rev 6.1.1.0 (2015/01/17) 総合計を最初の行に追加するかどうか(FirstTotal)の属性を追加
525         *
526         * @return true:対象 false:非対象
527         */
528        public boolean useFirstTotal() {
529                return StringUtil.nval( editVals[EDIT_KEY_FIRSTTOTAL], false );
530        }
531
532        /**
533         * 表示順カラムをCSV形式で返します。
534         * カラムの並び順が表示順としての優先順になります。
535         * また、降順で表示するカラムについては、カラム名の先頭に"!"が付加されます。
536         *
537         * @return 標準順カラムの一覧(CSV形式)
538         */
539        public String getOrderByClms() {
540                return editVals[EDIT_KEY_ORDERBY];
541        }
542
543        /**
544         * 指定されたカラムの表示順の優先番号を返します。
545         * 指定カラムが標準として指定されていない場合は、""(ゼロストリング)を返します。
546         *
547         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。
548         *
549         * @param clm カラム
550         *
551         * @return 表示順の優先番号
552         * @og.rtnNotNull
553         */
554        public String getOrder( final String clm ) {
555                // ConcurrentMap#getOrDefault(Object,V) を使用して、Map の値が null のときの初期値を返します。
556                return clm == null || editVals[EDIT_KEY_ORDERBY] == null
557                                        ? ""
558                                        : orderMap.getOrDefault( clm , "" );
559        }
560
561        /**
562         * 指定されたカラムの表示順指定が降順であるかどうかを返します。
563         * 標準と指定されていない場合は、falseを返します。
564         *
565         * @param clm カラム
566         *
567         * @return true:降順 false:昇順
568         */
569        public boolean isOrderByDesc( final String clm ) {
570                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
571                // 条件反転注意
572                return clm != null && orderByDescClms != null && ( ","+orderByDescClms+"," ).indexOf( ","+clm+"," ) >= 0 ;
573        }
574
575        /**
576         * 並び替え処理を行うかどうかを返します。
577         * これは、表示順カラムが指定されているか、と同じ意味です。
578         *
579         * @return true:対象 false:非対象
580         */
581        public boolean useOrderBy() {
582                return editVals[EDIT_KEY_ORDERBY] != null && editVals[EDIT_KEY_ORDERBY].length() > 0 ;
583        }
584
585        /**
586         * この編集設定オブジェクトが、共通(全ユーザー公開)編集か
587         * どうかを返します。
588         *
589         * @return 0以外:共通 0:個人のみ
590         */
591        public boolean isCommon() {
592                return StringUtil.nval( editVals[EDIT_KEY_COMMON], false );
593        }
594
595        /**
596         * 画面IDに対応した、内部のキーと値の各要素に対して指定されたアクションを実行します。
597         *
598         * getEditKeys(String,String) で得られるキーの文字列配列と、getEditVals()で得られる値の文字列配列
599         * を、順次、action メソッドに渡していきます。
600         * キーの文字列配列の作成時の編集名は、このオブジェクトの編集名を使用します。
601         *
602         * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。新規追加
603         *
604         * @param guikey 画面ID
605         * @param action 各要素に対して実行される関数型インタフェース( editKey、editVal )
606         */
607        public void forEach( final String guikey, final BiConsumer<String ,String> action ) {
608                final String keyNm = "_" + guikey + "_" + editVals[EDIT_KEY_NAME];
609
610                for( int i=0; i<EDIT_KEYS.length; i++ ) {
611                        action.accept( EDIT_KEYS[i] + keyNm , editVals[i] );
612                }
613        }
614}