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.html;
017
018import java.util.Arrays;
019import java.util.Iterator;
020import java.util.List;
021import java.util.Map;
022import java.util.concurrent.ConcurrentMap;                                              // 6.4.3.3 (2016/03/04)
023import java.util.stream.Collectors;                                                             // 6.4.3.4 (2016/03/11)
024import java.io.Writer;
025import java.io.IOException;
026
027import org.opengion.fukurou.system.HybsConst ;                                  // 6.1.0.0 (2014/12/26)
028import org.opengion.fukurou.util.StringUtil;
029import org.opengion.fukurou.util.Attributes;
030
031import org.opengion.hayabusa.common.HybsSystem;
032import org.opengion.hayabusa.common.HybsSystemException;
033import org.opengion.hayabusa.db.DBColumn;
034import org.opengion.hayabusa.db.DBTableModel;
035import org.opengion.hayabusa.db.DBColumnConfig;
036import org.opengion.hayabusa.resource.ResourceManager;
037
038/**
039 * ViewForm インターフェース の実装Abstractクラスです。
040 * これを,共通のスーパークラスとして 各種表示フォーム(例:HTML表示等)に使います。
041 *
042 * このクラス は、setter/getterメソッドのデフォルト実装を提供しています。
043 * 各種表示フォームに対応したサブクラス上で, create() をオーバーライドして下さい。
044 *
045 * @og.group 画面表示
046 *
047 * @version  4.0
048 * @author       Kazuhiko Hasegawa
049 * @since    JDK5.0,
050 */
051public abstract class AbstractViewForm implements ViewForm {
052        // 5.2.1.0 (2010/10/01)
053        // 6.1.1.0 (2015/01/17) BulkSet用の表示サイズは、一覧側のサイズになります。
054
055        /** システムの改行コードを設定します。*/
056        protected static final String CR                 = HybsConst.CR;                        // 6.1.0.0 (2014/12/26) refactoring
057        /** StringBilderなどの初期値を設定します。   {@value} */
058        protected static final int BUFFER_MIDDLE = HybsConst.BUFFER_MIDDLE;     // 6.1.0.0 (2014/12/26) refactoring
059        /** StringBilderなどの初期値を設定します。   {@value} */
060        protected static final int BUFFER_LARGE  = HybsConst.BUFFER_LARGE;      // 6.1.0.0 (2014/12/26) refactoring
061
062        // 3.8.0.3 (2005/07/15) 新しいヘッダー固定用のDIV要素を分ける。
063        private static final String LAYER_ST0 = "" ;
064        private static final String LAYER_END0 = "" ;
065        private static final String LAYER_END2 = "<a href=\"#top\" name=\"h_end\" id=\"h_end\" ></a></div></div></div></div>" ;
066
067        // 5.1.8.0 (2010/07/01) groupClass のタイプを定義します。
068        /** カラムのグループ化指定の enum 定数です。 */
069        private static enum CLM_GRP { KIGO , CHAR };
070
071        private String                  name                    = "";           // メニューの名前
072        private DBTableModel    table                   ;
073        private DBColumn[]              dbColumn                ;
074        private boolean[]               clmWritable     ;
075        private boolean[]               writeCtrl               ;                       // 3.8.0.9 (2005/10/17)
076        private boolean[]               clmDisplay              ;
077        private boolean[]               clmGroup                ;                       // 3.8.5.0 (2006/03/20)
078        private String                  groupClass              = "";           // 5.1.8.0 (2010/07/01)
079        private boolean                 useGroupDir             ;                       // 6.7.3.0 (2017/01/27)
080        private CLM_GRP                 groupType               ;                       // 5.1.8.0 (2010/07/01)
081        private boolean[]               sortKeys                ;                       // 3.6.0.0 (2004/09/17)
082        private boolean[]               useEventCols    ;                       // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
083        private boolean                 useSorterKeys   ;                       // 3.6.0.0 (2004/09/17) 内部変数
084        private String                  sorterQuery             = "";           // 3.6.0.0 (2004/09/17) 内部変数
085        private String                  viewFormID              ;
086        private int                     startNo                 ;
087        private int                     pageSize                = HybsSystem.sysInt( "HTML_PAGESIZE" ) ;
088        private boolean                 rowWritableFlag ;                               // 1カラム目が writable か?
089        private ViewMarker              viewLink                ;
090        private ViewMarker              viewMarker              ;
091        private ViewMarker              editMarker              ;                               // 3.8.6.1 (2006/10/20)
092        private String                  selectedType    = "checkbox";
093        private String                  numberType              = "sequence" ;  // 3.5.1.0 (2003/10/03) 新規作成
094        private int                             numberTypeClm   = -1;                   // 3.5.1.0 (2003/10/03) 新規作成
095        private String[]                numberTypeData  ;                               // 3.5.1.0 (2003/10/03) 新規作成
096        private String                  optTypeAttri    ;
097        private boolean                 noMessage               ;
098        private int                     backLinkCount   ;
099        private int                             headerSkipCount ;                               // 0:通常ヘッダ、n:n回ごとに現れる
100        private boolean                 skip                    = ViewForm.DEFAULT_SKIP;        // 3.5.3.1 (2003/10/31)
101        private int                             useCheckControl ;                               // 3.7.0.1 (2005/01/31)
102        private boolean                 useTableSorter  = HybsSystem.sysBool( "VIEW_USE_TABLE_SORTER" ) ;       // 3.5.4.7 (2004/02/06)
103        private boolean                 numberDisplay   = true ;                // 3.5.5.0 (2004/03/12)
104        private int                             scrollRowNo             = -1;                   // 3.7.0.3 (2005/03/01)
105
106        // 3.5.4.6 (2004/01/30) ヘッダー文字列を定義しておきます。
107        private static final String NO_HEADER = "No" ;
108
109        // 3.5.4.8 (2004/02/23) ViewParamTag のパラメータを受け取ります。
110        /** 6.4.3.1 (2016/02/12) 作成元のMapを、HashMap から ConcurrentHashMap に置き換え。  */
111        private ConcurrentMap<String,String> viewParam  ;               // 6.4.3.3 (2016/03/04)
112
113        //5.5.8.3 (2012/11/17) Stringでなく、Objectタイプをもてるようにする(積上げガント対応)
114        private List<String[]> viewArrayList    ; // 5.5.9.0 (2012/12/03) ObjectではなくArrayList
115
116        private int columnCount ;       // 3.5.5.7 (2004/05/10)
117        private int rowCount    ;       // 4.0.0 (2006/01/06)
118
119        // 3.5.6.2 (2004/07/05) ゼブラ模様の指定を、ViewForm としてサポート
120        // 0(ゼブラなし)、-1(ワーニング)、-2以下(エラー)、1(ゼブラ)、2以上(行数まとめ)
121        private int bgColorCycle   = 1 ;
122        // 行ごとに色を変更する時の、デフォルトクラス属性
123        private static final String BG_COLOR_ROW0 = " class=\"row_0\"";
124        // 行ごとに色を変更する時の、切り替え後クラス属性
125        private static final String BG_COLOR_ROW1 = " class=\"row_1\"";
126
127        // 行ごとに色を変更する時の、切り替え後クラス属性
128        private static final String BG_COLOR_ROWSEL = " class=\"row_sel\"";             // 3.7.0.3 (2005/03/01)
129
130        // 警告時の行ごとに色を変更する時の、デフォルトクラス属性
131        private static final String BG_WARNING_COLOR_ROW0 = " class=\"row_0 row_warning\"";
132        // 警告時の行ごとに色を変更する時の、切り替え後クラス属性
133        private static final String BG_WARNING_COLOR_ROW1 = " class=\"row_1 row_warning\"";
134
135        // エラー時の行ごとに色を変更する時の、デフォルトクラス属性
136        private static final String BG_ERROR_COLOR_ROW0 = " class=\"row_0 row_error\"";
137        // エラー時の行ごとに色を変更する時の、切り替え後クラス属性
138        private static final String BG_ERROR_COLOR_ROW1 = " class=\"row_1 row_error\"";
139
140        private String colorRow0 = BG_COLOR_ROW0 ;
141        private String colorRow1 = BG_COLOR_ROW1 ;
142
143        // 5.1.8.0 (2010/07/01) 行に対して、動的にクラス属性を付与するカラム名を指定します。
144        private int bgColorClsClmNo  = -1;
145
146        // 3.5.6.4 (2004/07/16)
147        private boolean useScrollBar = HybsSystem.sysBool( "VIEW_USE_SCROLLBAR" ) ;
148
149        // 3.6.0.0 (2004/09/17)
150        private boolean firstChecked    ;
151
152        // 3.7.1.1 (2005/05/31) SEL_ROW機能使用時に、BG_COLOR_ROWSEL の使用 有/無を指定します。
153        private boolean useSelRowColor  ;
154
155        // 4.0.0 (2007/04/16) tableタグを出力するときに付与します。
156        private String  clazz                   = "viewTable";
157
158        // 4.0.0.0 (2007/11/27) ResourceManagerを設定します。(クロス集計で使用)
159        private ResourceManager resourceManager ;
160
161        // 4.2.0.0 (2008/03/03) ビューの幅と高さを指定できるようにします。
162        private String  height          ;
163        private String  width           ;
164
165        // 4.3.1.0 (2008/09/08)
166        private boolean skipNoEdit      ;
167
168        // 4.3.3.0 (2008/10/01) 画面遷移なしモード時に各行に出力する行番号及び改廃Cのキーを定義します。
169        private static final String HIDDEN_ROW_KEY =    "rid";          // 6.4.1.1 (2016/01/16) hiddenRowKey  → HIDDEN_ROW_KEY refactoring
170        private static final String HIDDEN_CDKH_KEY =   "kh";           // 6.4.1.1 (2016/01/16) hiddenCdkhKey → HIDDEN_CDKH_KEY refactoring
171
172        private boolean noTransition    ;
173
174        // 5.1.7.0 (2010/06/01) ViewFormのキャッシュ復元を画面ID単位に行う
175        private String gamenId                  ;
176
177        // 5.2.1.0 (2010/10/01) 一括入力カラムのアシスト機能を利用するカラムを指定します。
178        private boolean[]       clmBulkSet      ;
179
180        // 5.5.4.2 (2012/07/13) mustとmustAnyを保持する
181        private String[]        nullCheck       ;
182        private String[]        mustAnyCheck;           // 3.8.0.9 (2005/10/17)
183
184        // 5.9.5.3 (2016/02/26)
185        // 6.4.6.1 (2016/06/03) tableId 廃止(利用目的を明確にするため、パラメータ名をviewClassに変更)
186        private String viewClass = "VIEW_" + HybsSystem.TBL_MDL_KEY;    // 初期値
187
188        /**
189         * デフォルトコンストラクター
190         *
191         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
192         */
193        protected AbstractViewForm() { super(); }               // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
194
195        /**
196         * 初期化します。
197         * ここでは、内部で使用されているキャッシュをクリアし、
198         * 新しいモデル(DBTableModel)と言語(lang) を元に内部データを再構築します。
199         * なお、テーブルモデルに対してViewFormで変更を加える場合は、変更処理を行った後に
200         * このメソッドを実行するようにして下さい。
201         *
202         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
203         * @og.rev 3.5.6.1 (2004/06/25) lang 言語コード 属性を削除します。
204         * @og.rev 3.5.6.3 (2004/07/12) 呼ばれたら、必ず初期化するように修正(元に戻す)
205         * @og.rev 3.6.0.0 (2004/09/17) sortKeys 追加
206         * @og.rev 3.8.0.9 (2005/10/17) writeCtrl 追加
207         * @og.rev 3.8.5.0 (2006/03/20) clmGroup 追加
208         * @og.rev 4.0.0.0 (2006/01/06) rowCount 追加
209         * @og.rev 4.0.1.0 (2007/12/13) コメントの追加
210         * @og.rev 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
211         * @og.rev 5.2.0.0 (2010/09/01) 2回連続登録時に選択行にスクロールしないバグを修正。
212         * @og.rev 5.2.1.0 (2010/10/01) 一括入力カラムのアシスト機能を利用するカラム(clmBulkSet) 追加
213         * @og.rev 5.5.4.2 (2012/07/13) mustとmustany保持
214         *
215         * @param       table   DBTableModelオブジェクト
216         */
217        public void init( final DBTableModel table ) {
218                this.table = table;
219                if( table != null ) {
220                        rowCount        = table.getRowCount();                  // 4.0.0 (2006/01/06)
221                        columnCount = table.getColumnCount();
222                        clmWritable = new boolean[columnCount];
223                        writeCtrl       = new boolean[columnCount];     // 3.8.0.9 (2005/10/17)
224                        clmDisplay      = new boolean[columnCount];
225                        clmGroup        = new boolean[columnCount];     // 3.8.5.0 (2006/03/20)
226                        sortKeys        = new boolean[columnCount];     // 3.6.0.0 (2004/09/17)
227                        dbColumn        = new DBColumn[columnCount];
228                        useEventCols= new boolean[columnCount]; // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
229                        clmBulkSet  = new boolean[columnCount]; // 5.2.1.0 (2010/10/01)
230                        Arrays.fill( clmWritable,DEFAULT_CLM_WRITABLE );        // カラムの書込み許可
231                        Arrays.fill( writeCtrl,false );                                         // 書き込み制御の許可
232                        Arrays.fill( clmDisplay ,true );                                        // カラムの表示許可
233                        Arrays.fill( clmGroup ,false );                                         // 3.8.5.0 (2006/03/20) カラムのグループ化
234                        Arrays.fill( sortKeys ,false );                                         // すべてリンクしないに設定する。
235                        Arrays.fill( useEventCols, false );                                     // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
236                        Arrays.fill( clmBulkSet, false );                                       // 5.2.1.0 (2010/10/01)
237                        for( int i=0; i<columnCount; i++ ) {
238                                dbColumn[i] = table.getDBColumn( i );
239                        }
240
241                        // 1カラム目(最初のカラム=配列0番目)が writable か?
242                        rowWritableFlag = "WRITABLE".equalsIgnoreCase( getColumnName(0) );
243
244                        // 5.2.0.0 (2010/09/01) 2回連続登録時に選択行にスクロールしないバグを修正。
245                        scrollRowNo = -1;
246                        firstChecked = false;
247
248                        // 5.5.4.2 (2102/07/13)
249                        nullCheck        = table.getMustArray();
250                        mustAnyCheck = table.getMustAnyArray();
251                }
252        }
253
254        /**
255         * 内部の DBTableModel を返します。
256         *
257         * @return      DBTableModelオブジェクト
258         */
259        public DBTableModel getDBTableModel() {
260                return table;
261        }
262
263        /**
264         * ViewForm の識別IDをセットします。
265         * これは、ViewFormFactory でプールする場合の識別キーになります。
266         * プールに戻すときに自分自身に この識別IDを使用します。
267         *
268         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
269         * @og.rev 3.5.6.2 (2004/07/05) メソッド名がまぎらわしい為、変更します。
270         *
271         * @param       viewFormID 識別ID
272         */
273        public void setId( final String viewFormID ) {
274                this.viewFormID = viewFormID;
275        }
276
277        /**
278         * ViewForm の識別IDを返します。
279         * これは、ViewFormFactory でプールする場合の識別キーになります。
280         * プールに戻すときに自分自身に この識別IDを使用します。
281         *
282         * @og.rev 3.5.6.2 (2004/07/05) メソッド名がまぎらわしい為、変更します。
283         *
284         * @return      識別ID
285         */
286        public String getId() {
287                return viewFormID;
288        }
289
290        /**
291         * DBTableModel から HTML文字列を作成して返します。
292         *
293         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
294         *
295         * @return      DBTableModelから作成された HTML文字列
296         */
297        public String create() {
298                return create( 0, rowCount );
299        }
300
301        /**
302         * DBTableModel から View文字列を作成して、Writer にセットします。
303         * 処理内容は、create( int , int ) と同じですが、中間の文字列(StringBuilder)
304         * を作成せずに、直接、Writer に書き出します。
305         * よって、データ作成途中でエラーが発生しても、すでにいくつかのデータは
306         * クライアントに返されています。
307         *
308         * @og.rev 5.0.0.1 (2009/08/15) 直接出力用の Writer 引数追加
309         *
310         * @param  startNo        表示開始位置
311         * @param  pageSize   表示件数
312         * @param  wrt            直接登録用の Writer
313         */
314        public void create( final int startNo, final int pageSize, final Writer wrt ) throws IOException {
315                final String errMsg = "このメソッドは、直接登録用の Writer のビューでのみ使用できます。";
316                throw new UnsupportedOperationException( errMsg );
317        }
318
319        /**
320         * 内容をクリア(初期化)します。
321         *
322         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
323         * @og.rev 3.5.1.0 (2003/10/03) displayNumber 廃止。numberType 新規追加。
324         * @og.rev 3.5.2.0 (2003/10/20) headerSkipCount属性を追加
325         * @og.rev 3.5.3.1 (2003/10/31) skip属性を追加
326         * @og.rev 3.5.4.3 (2004/01/05) useCheckControl属性を追加
327         * @og.rev 3.5.4.3 (2004/01/05) viewFormID属性を削除(初期化しない)
328         * @og.rev 3.5.4.7 (2004/02/06) useTableSorter属性を追加
329         * @og.rev 3.5.4.7 (2004/02/06) columnMaxSize は使用されていないので削除します。
330         * @og.rev 3.5.4.8 (2004/02/23) ViewParamTag のパラメータを追加します。
331         * @og.rev 3.5.5.0 (2004/03/12) numberType 属性の "delete" 値追加に伴なう、numberDisplay 変数の追加。
332         * @og.rev 3.5.6.2 (2004/07/05) bgColorCycle 変数の追加。
333         * @og.rev 3.5.6.4 (2004/07/16) useScrollBar 変数の追加。
334         * @og.rev 3.6.0.0 (2004/09/17) sortKeys , firstChecked , useSorterKeys , sorterQuery 変数の追加。
335         * @og.rev 3.7.0.1 (2005/01/31) 全件チェックコントロール変更( boolean ⇒ int )
336         * @og.rev 3.7.1.1 (2005/05/31) useSelRowColor 変数の追加。
337         * @og.rev 3.8.0.3 (2005/07/15) scrollBarType 変数の追加
338         * @og.rev 3.8.0.9 (2005/10/17) writeCtrl 変数の追加
339         * @og.rev 3.8.5.0 (2006/03/20) clmGroup 変数の追加
340         * @og.rev 3.8.6.1 (2006/10/20) editMarker 変数の追加
341         * @og.rev 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
342         * @og.rev 5.1.8.0 (2010/07/01) groupClass , groupType 変数の追加
343         * @og.rev 5.1.8.0 (2010/07/01) bgColorClsClmNo 属性を追加します。
344         * @og.rev 5.2.1.0 (2010/10/01) 一括入力カラムのアシスト機能を利用するカラム(clmBulkSet) 追加
345         * @og.rev 5.5.4.2 (2012/07/13) mustとmustany追加
346         * @og.rev 5.5.9.0 (2012/12/03) viewArrayList追加(viewObjectは削除)
347         * @og.rev 6.7.3.0 (2017/01/27) useGroupDir追加
348         */
349        public void clear() {
350                name                    = "";                           // メニューの名前
351                table                   = null;
352                dbColumn                = null;
353                clmWritable     = null;
354                writeCtrl               = null;                 // 3.8.0.9 (2005/10/17)
355                clmDisplay              = null;
356                clmGroup                = null;                 // 3.8.5.0 (2006/03/20)
357                groupClass              = "";                   // 5.1.8.0 (2010/07/01)
358                useGroupDir             = false;                // 6.7.3.0 (2017/01/27)
359                groupType               = null;                 // 5.1.8.0 (2010/07/01)
360                sortKeys                = null;                 // 3.6.0.0 (2004/09/17)
361                useSorterKeys   = false;                // 3.6.0.0 (2004/09/17)
362                sorterQuery             = "";                   // 3.6.0.0 (2004/09/17)
363                startNo                 = 0 ;
364                pageSize                = HybsSystem.sysInt( "HTML_PAGESIZE" ) ;
365                rowWritableFlag = false;        // 1カラム目が writable か?
366                viewLink                = null;
367                viewMarker              = null;
368                editMarker              = null;         // 3.8.6.1 (2006/10/20)
369                backLinkCount   = 0;
370                selectedType    = "checkbox";
371                numberType              = "sequence";
372                numberTypeClm   = -1;
373                numberTypeData  = null;
374                headerSkipCount = 0;    // 0:通常ヘッダ、n:n回ごとに現れる
375                skip                    = ViewForm.DEFAULT_SKIP;        // 3.5.3.1 (2003/10/31)
376                useCheckControl = 0 ;           // 3.7.0.1 (2005/01/31)
377                viewParam               = null;         // 3.5.4.8 (2004/02/23)
378                viewArrayList   = null;         // 5.5.8.3 (2012/12/03) 
379                numberDisplay   = true ;        // 3.5.5.0 (2004/03/12)
380                columnCount             = 0;            // 3.5.5.7 (2004/05/10)
381                bgColorCycle    = 1;            // 3.5.6.2 (2004/07/05)
382                bgColorClsClmNo = -1;           // 5.1.8.0 (2010/07/01)
383                colorRow0               = BG_COLOR_ROW0 ;               // 3.5.6.2 (2004/07/05)
384                colorRow1               = BG_COLOR_ROW1 ;               // 3.5.6.2 (2004/07/05)
385                useScrollBar    = HybsSystem.sysBool( "VIEW_USE_SCROLLBAR" ) ;  // 3.5.6.4 (2004/07/16)
386                firstChecked    = false;
387                useSelRowColor  = false;        // 3.7.1.1 (2005/05/31)
388                height                  = null;         // 4.2.0.0 (2008/03/18)
389                width                   = null;         // 4.2.0.0 (2008/03/18)
390                skipNoEdit              = false;        // 4.3.2.0 (2008/09/10)
391                useEventCols    = null;         // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
392                clmBulkSet              = null;         // 5.2.1.0 (2010/10/01) 一括入力カラムのアシスト機能を利用するカラム(clmBulkSet) 追加
393                nullCheck               = null;         // 5.5.4.2 (2012/07/13)
394                mustAnyCheck    = null;         // 5.5.4.2 (2012/07/13)
395        }
396
397        /**
398         * テーブルのヘッダーの前に、そのデータの表示範囲を示す文字列を作成します。
399         * [開始No - 終了No]/[件数] です。
400         *
401         * @og.rev 2.0.0.2 (2002/09/24) [1 - 4]/[4] 等のメッセージ出力後の &lt;br&gt; 出力を中止。
402         * @og.rev 4.3.6.0 (2008/04/01) [1 - 4]/[4]のメッセージをJavaScriptで入れ替えるように変更
403         * @og.rev 4.3.8.0 (2009/08/01) 同メッセージ複数対応及びheadでコントロール可能にする
404         *
405         * @param  stNo    表示開始位置
406         * @param  pgSize  表示件数
407         *
408         * @return      テーブルのヘッダータグ文字列
409         * @og.rtnNotNull
410         */
411        protected String getCountForm( final int stNo, final int pgSize ) {
412                if( noMessage ) { return ""; }
413
414                final int lstNo = stNo+pgSize > rowCount ? rowCount : stNo+pgSize ;
415
416                // 6.0.2.5 (2014/10/31) char を append する。
417                final StringBuilder out = new StringBuilder( BUFFER_MIDDLE )
418                        .append( "<div class=\"orgRowCntMsg\">" )
419                        .append( '[' ).append( stNo+1 ).append( " - " ).append( lstNo )
420                        .append( "]/[" ).append( rowCount )
421                        .append( "]</div>" );
422
423                return out.toString() ;
424        }
425
426        /**
427         * カラムのラベル名を返します。
428         * カラムの項目名に対して,見える形の文字列を返します。
429         * 一般には,リソースバンドルと組合せて,各国ロケール毎にラベルを
430         * 切替えます。
431         *
432         * @param       column カラム番号
433         *
434         * @return      カラムのラベル名
435         */
436        protected String getColumnLabel( final int column ) {
437                return dbColumn[column].getLabel();
438        }
439
440        /**
441         * カラム名を返します。
442         * データベースで検索したときのカラムの項目名を返します。
443         *
444         * @param       column カラム番号
445         *
446         * @return      カラム名
447         */
448        protected String getColumnName( final int column ) {
449                return dbColumn[column].getName();
450        }
451
452        /**
453         * row行,colum列 のデータの値を返します。
454         *
455         * @param       row     行番号
456         * @param       column カラム番号
457         *
458         * @return      row行,colum列 のデータの値
459         */
460        protected String getValue( final int row,final int column ) {
461                return table.getValue( row,column ) ;
462        }
463
464        /**
465         * row行,colum列 のデータの値を返します。
466         * これは、データの値そのものではなく、その値のラベル文字を返します。
467         *
468         * @og.rev 3.8.0.9 (2005/10/17) 互換性確保のメソッド
469         *
470         * @param       row     行番号
471         * @param       column カラム番号
472         *
473         * @return      row行,colum列 のデータの値
474         * @og.rtnNotNull
475         */
476        protected String getRendererValue( final int row,final int column) {
477                return getRendererValue( row,column,getValue( row,column ) );
478        }
479
480        /**
481         * row行,colum列 のデータの値を返します。
482         * これは、データの値そのものではなく、その値のラベル文字を返します。
483         *
484         * @og.rev 3.8.0.9 (2005/10/17) writableControl 追加による引数変更
485         * @og.rev 3.8.5.0 (2006/03/20) clmGroup 追加によるグループ化処理
486         * @og.rev 4.0.0.0 (2005/11/30) 行番号に対応した値を返すように変更します。
487         * @og.rev 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
488         * @og.rev 5.1.8.0 (2010/07/01) カラムグループの groupClass 対応
489         * @og.rev 6.7.3.0 (2017/01/27) useGroupDir 追加
490         *
491         * @param       row             行番号
492         * @param       column  カラム番号
493         * @param       inVal   データの値
494         *
495         * @return      row行,colum列 のデータの値
496         */
497        protected String getRendererValue( final int row,final int column , final String inVal ) {
498                String val = dbColumn[column].getRendererValue( row,inVal );
499
500                // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
501                if( useEventCols[column] && isWritable( row ) ) {
502                        val = dbColumn[column].getEventColumnTag( val, getValue( row,column ), row, false );
503                }
504                if( viewLink != null ) {
505                        val = viewLink.getMarkerString( row,column,val );
506                }
507                if( viewMarker != null ) {
508                        val = viewMarker.getMarkerString( row,column,val );
509                }
510
511                // 5.1.8.0 (2010/07/01) groupClass 対応:空文字の場合を考慮し、最後に処理を行う。
512                // 出力する値が、空文字列なら、前行と同じでも、空文字にしておきます。
513
514                // 6.7.3.0 (2017/01/27) useGroupDir 追加
515                if( groupType != null && clmGroup[column] && inVal != null && val != null && val.length() > 0 ) {
516                        if( useGroupDir && column > 0 && inVal.equals( getValue( row,column-1 ) ) ||
517                                !useGroupDir && row > 0 && row != startNo && inVal.equals( getValue( row-1,column ) ) ) {
518
519                                val = groupType == CLM_GRP.KIGO ? groupClass
520                                                                                                : "<span class=\"" + groupClass + "\">" + val + "</span>";
521                        }
522                }
523
524                return val;
525        }
526
527        /**
528         * row行,colum列 のデータの値をHTML文字列に変換して返します。
529         * リソースバンドルが登録されている場合は,リソースに応じた
530         * HTML文字列を作成します。
531         *
532         * @og.rev 3.8.0.9 (2005/10/17) writableControl 追加による引数変更
533         * @og.rev 3.8.6.1 (2006/10/20) editMarker 追加
534         * @og.rev 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
535         *
536         * @param       row             行番号
537         * @param       column  カラム番号
538         * @param       inVal   データの値
539         *
540         * @return      row行,colum列 のデータの値
541         */
542        protected String getEditorValue( final int row, final int column, final String inVal ) {
543                String val = dbColumn[column].getEditorValue( row,inVal );
544                // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
545                if( useEventCols[column] ) {
546                        val = dbColumn[column].getEventColumnTag( val, getValue( row,column ), row, true );
547                }
548                if( editMarker != null ) {
549                        val = editMarker.getMarkerString( row,column,val );
550                }
551
552                return val;
553        }
554
555        /**
556         * row行,colum列 のデータの値をHTML文字列に変換して返します。
557         * リソースバンドルが登録されている場合は,リソースに応じた
558         * HTML文字列を作成します。
559         * リソースバンドルが登録されていない場合は,getValue( int row,int column )を
560         * 返します。
561         * 新規機能として、writableControl によるエディター・レンデラー指定が出来ます。
562         * その場合、表示/編集ともに、先頭のアンダーバーは削除されます。
563         *
564         * @og.rev 3.8.0.9 (2005/10/17) writableControl によるエディター・レンデラー指定
565         *
566         * @param       row     行番号
567         * @param       column カラム番号
568         *
569         * @return      row行,colum列 のデータの値
570         * @og.rtnNotNull
571         */
572        protected String getValueLabel( final int row, final int column ) {
573                String val = getValue( row,column ) ;
574                boolean isEdit = isColumnWritable( column ) && isWritable( row ) ;
575                if( writeCtrl[column] && val != null && val.length() > 0 && val.charAt(0) == '_' ) {
576                        isEdit = false;
577                        val = val.substring(1);         // 先頭の '_' を削除
578                }
579
580                // 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
581                return isEdit ? getEditorValue( row,column,val ) : getRendererValue( row,column,val );
582        }
583
584        /**
585         * カラムのクラスを文字列にした名称を返します。
586         * これは,HTML上の各種タグに,データベース定義に応じたクラスを
587         * セットし,CSS(Cascading Style Sheet)の class="xxxxx" とする事により
588         * 各種スタイルを表現するのに使用します。
589         *
590         * ここでは, カラムリソースの DBTYPE 属性で指定の文字列(X,S9,KXなど)を返します。
591         *
592         * ※ 従来は、class属性に使用する値を取得していましたが、
593         *    org.opengion.plugin.view.ViewForm_HTMLTable#makeNthChild( StringBuilder , int , String )
594         *    の引数に渡すことをメインに使用します。
595         *
596         * @og.rev 4.0.0.0 (2005/01/31) 新規作成(getColumnClassName ⇒ getColumnDbType)
597         * @og.rev 5.2.2.0 (2010/11/01) className が VARCHAR2,NUMBER以外の場合は、合わせて出力します。
598         * @og.rev 6.4.4.2 (2016/04/01) contains 判定を行う新しいメソッドを使用します。
599         * @og.rev 6.4.5.0 (2016/04/08) protected化と、純粋なDBTYPE 属性を返すように変更。
600         *
601         * @param   column カラム番号
602         *
603         * @return  カラムの DBTYPE 属性
604         */
605        protected String getColumnDbType( final int column ) {
606                return dbColumn[column].getDbType();
607        }
608
609        /**
610         * カラムのクラスを文字列にした名称を返します。
611         * 内容的には、カラムの className の値と、dbTypeの値をマージした値になります。
612         * さらに、editorAttributesの "class"キーワードの値もマージします。
613         * ただし、この値には、must属性も設定されているため、それだけは除外します。
614         * 各種スタイルを表現するのに使用します。
615         *
616         * @og.rev 6.4.5.0 (2016/04/08) 新規追加
617         *
618         * @param   column カラム番号
619         *
620         * @return  カラムの DBTYPE 属性
621         */
622        protected String getClassName( final int column ) {
623                return dbColumn[column].getClassName();
624        }
625
626        /**
627         * カラムが書き込み可能かどうかを返します。
628         *
629         * @param       column カラム番号
630         *
631         * @return      書込み可能(true)/不可能(false)
632         */
633        protected boolean isColumnWritable( final int column ) {
634                return clmWritable[column];
635        }
636
637        /**
638         * カラムが書き込み可能かどうかをセットします。
639         *
640         * @param       column カラム番号
641         * @param       rw 書込み可能(true)/不可能(false)
642         */
643        public void setColumnWritable( final int column,final boolean rw ) {
644                clmWritable[column] = rw;
645        }
646
647        /**
648         * 書き込み可能カラム名を、CSV形式で与えます。
649         * 例:"OYA,KO,HJO,SU,DYSET,DYUPD"
650         * setColumnWritable( int column,boolean rw ) の簡易版です。
651         * null を与えた場合は,なにもしません。
652         * また、全カラムについて、有効にする場合は、columnName="*" を設定します。
653         *
654         * @og.rev 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
655         * @og.rev 5.1.8.0 (2010/07/01) 内部ロジック変更(setBooleanArray)
656         *
657         * @param       columnName      カラム名
658         */
659        public void setColumnWritable( final String columnName ) {
660                if( columnName != null ) {
661                        setBooleanArray( columnName,true,clmWritable );
662
663                        // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
664                        setUseEventCols();
665                }
666        }
667
668        /**
669         * 書き込み不可カラム名を、CSV形式で与えます。
670         * 例:"OYA,KO,HJO,SU,DYSET,DYUPD"
671         * null を与えた場合は,なにもしません。
672         * また、全カラムについて、有効にする場合は、columnName="*" を設定します。
673         *
674         * @og.rev 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
675         * @og.rev 5.1.8.0 (2010/07/01) 内部ロジック変更(setBooleanArray)
676         *
677         * @param       columnName      カラム名
678         */
679        public void setNoWritable( final String columnName ) {
680                if( columnName != null ) {
681                        setBooleanArray( columnName,false,clmWritable );
682                        // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
683                        setUseEventCols();
684                }
685        }
686
687        /**
688         * 各項目がイベントカラムをするかどうかをセットします。
689         *
690         * @og.rev 5.1.7.0 (2010/06/01) 新規作成(動的プルダウン実装見直し)
691         */
692        private void setUseEventCols() {
693                for( int column=0; column<dbColumn.length; column++ ) {
694                        final String evCols = dbColumn[column].getEventColumn();
695                        if( evCols != null && evCols.length() > 0 ) {
696                                final String[] evColsArr = StringUtil.csv2Array( evCols );
697                                for( int i=0; i<evColsArr.length; i++ ) {
698                                        String evCol = evColsArr[i];
699                                        if( evCol.charAt(0) == '_' ) { evCol = evCol.substring( 1 ); }
700                                        if( isColumnWritable( table.getColumnNo( evCol ) ) ) {
701                                                useEventCols[column] = true;
702                                                break;
703                                        }
704                                }
705                        }
706                }
707        }
708
709        /**
710         * 行指定の書込み許可を返します。
711         *
712         * @og.rev 3.5.4.2 (2003/12/15) writable カラムが "2" のときも、書き込み許可とする
713         * @og.rev 3.5.5.7 (2004/05/10) 判定ロジックを若干見直します。
714         *
715         * @param       row     行番号
716         *
717         * @return      書込み可能(true)/不可能(false)
718         */
719        protected boolean isWritable( final int row ) {
720                boolean rtn = table.isRowWritable( row );
721                if( rtn && rowWritableFlag ) {
722                        final String val = table.getValue( row,0 );
723                        rtn = "TRUE".equalsIgnoreCase( val )
724                                                || "1".equalsIgnoreCase( val )
725                                                || "2".equalsIgnoreCase( val ) ;
726
727                        if( ! rtn &&
728                                ! "FALSE".equalsIgnoreCase( val ) &&
729                                ! "0".equalsIgnoreCase( val ) &&
730                                ! "".equalsIgnoreCase( val ) ) {
731                                        final String errMsg = "writable は、TRUE,FALSE,0,1,2,null 以外指定できません。" +
732                                                                        "  row=[" + (row+1) + "]  val=[" + val + "]";
733                                        throw new HybsSystemException( errMsg );
734                        }
735                }
736                return rtn;
737        }
738
739        /**
740         * 書き込み可能な行(rowWritable == true)のチェックボックスに対して
741         * 初期値を 選択済みにするか、非選択済みにするかを指定します。
742         *
743         * @og.rev 3.5.4.2 (2003/12/15) writable カラムが "2" のとき、チェックを付ける。
744         *
745         * @param       row 行の指定
746         *
747         * @return      チェックON(true)/チェックOFF(false)
748         */
749        protected boolean isChecked( final int row ) {
750                boolean rtn = table.isRowChecked( row );
751                if( rowWritableFlag ) {
752                        final String val = table.getValue( row,0 );
753                        rtn = rtn || "2".equalsIgnoreCase( val ) ;
754                }
755                return rtn;
756        }
757
758        /**
759         * チェック済みの行の先頭に、フォーカスを当てる処理で、チェックの一つ前の
760         * 行番号欄にダミーのリンクを作成する為の判定を行います。
761         * つまり、指定の行番号の次の値が、チェックされているかどうかを判断します。
762         * さらに、これは、一番上位にチェックされている番号の時のみ
763         * 返します。(表示テーブル中、最高一回のみ、true が返る。)
764         *
765         * @og.rev 3.6.0.0 (2004/09/17) 新規作成
766         * @og.rev 3.7.0.3 (2005/03/01) setScrollRowNo の対応
767         * @og.rev 3.8.8.3 (2007/02/09) 最初の選択行 より指定行番号へのフォーカスを優先
768         * @og.rev 4.2.3.1 (2008/06/11) 1件目がチェックされている場合は、対象外とする。
769         * @og.rev 4.2.4.0 (2008/06/25) 1件目対象外の判定で、指定行番号へのフォーカスを優先する。
770         * @og.rev 5.1.1.1 (2009/12/02) 選択行アンカーは、自身の行に出す(default.js#focus2()も合わせて変更)
771         *
772         * @param       row     行の指定
773         *
774         * @return      チェックON(true)/チェックOFF(false)
775         */
776        protected boolean isFirstChecked( final int row ) {
777
778                // 最初の1回のみ、true を返す。よって、元がtrue なら、false を返す。
779                if( firstChecked ) { return false; }
780
781                // 指定の次の行を見るため、範囲オーバーしていないか確認
782                if( row >= rowCount ) { return false; } // 5.1.1.1 (2009/12/02)
783
784                final boolean rtn;
785                // 3.8.8.3 (2007/02/09) 最初の選択行 より指定行番号へのフォーカスを優先
786                if( scrollRowNo >= 0 ) {
787                        rtn = row == scrollRowNo ; // 5.1.1.1 (2009/12/02)
788                }
789                else {
790                        // 1件目がチェックされている場合は、対象外とする。4.2.3.1 (2008/06/11)
791                        if( row == 0 && table.isRowChecked( row ) ) {
792                                firstChecked = true;
793                                return false;
794                        }
795
796                        rtn = table.isRowChecked( row ); // 5.1.1.1 (2009/12/02)
797                }
798
799                // 最初の1回のみ、true を返す。よって、元がtrue なら、false を返す。
800                if( rtn ) { firstChecked = true; }
801                return rtn;
802        }
803
804        /**
805         * その行が、処理対象かどうかをチェックします。
806         * 処理対象かどうかは、書き込み可能な行(rowWritable == true)
807         * で且つ チェックされた行(rowChecked == true) とします。
808         * 例えば,NEXT/PREVでスキップ等の処理を行う場合は、 処理対象以外を
809         * スキップすることで実現できます。
810         *
811         * @param       row     行番号
812         *
813         * @return       処理対象(true)/処理対象でない(false)
814         */
815        public boolean isMarked( final int row ) {
816                return isWritable( row ) && isChecked( row ) ;
817        }
818
819        /**
820         * カラムが表示可能かどうかを返します。
821         * もし,表示不可の場合は,このカラムの全データが,表示対象から外されます。
822         *
823         * @param       column カラム番号
824         *
825         * @return      表示可能(true)/不可能(false)
826         */
827        protected boolean isColumnDisplay( final int column ) {
828                // 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
829                // 条件変更注意
830                return !( rowWritableFlag && column == 0 ) && clmDisplay[column];
831        }
832
833        /**
834         * 表示可能なカラムの数を返します。
835         *
836         * @return      表示可能なカラム数
837         */
838        protected int getColumnDisplayCount() {
839                int rtn = 0;
840                for( int i=0; i<columnCount; i++ ) {
841                        if( isColumnDisplay(i) ) { rtn++ ; }
842                }
843
844                return rtn;
845        }
846
847        /**
848         * カラムが表示可能かどうかをセットします。
849         * DBColumnのROLE属性による表示可否は、ViewFormTag で設定されます。
850         *
851         * @param       column カラム番号
852         * @param       rw 表示可能(true)/不可能(false)
853         */
854        public void setColumnDisplay( final int column,final boolean rw ) {
855                clmDisplay[column] = rw;
856        }
857
858        /**
859         * 表示可能カラム名を、CSV形式で与えます。
860         * 例:"OYA,KO,HJO,SU,DYSET,DYUPD"
861         * setColumnDisplay( int column,boolean rw ) の簡易版です。
862         * null を与えた場合は,なにもしません。
863         * また、全カラムについて、有効にする場合は、columnName="*" を設定します。
864         *
865         * @og.rev 5.1.8.0 (2010/07/01) 内部ロジック変更(setBooleanArray)
866         *
867         * @param       columnName      カラム名
868         */
869        public void setColumnDisplay( final String columnName ) {
870                setBooleanArray( columnName,true,clmDisplay );
871        }
872
873        /**
874         * 表示不可カラム名を、CSV形式で与えます。
875         * 例:"OYA,KO,HJO,SU,DYSET,DYUPD"
876         * null を与えた場合は,なにもしません。
877         * また、全カラムについて、有効にする場合は、columnName="*" を設定します。
878         *
879         * @og.rev 5.1.8.0 (2010/07/01) 内部ロジック変更(setBooleanArray)
880         *
881         * @param       columnName      カラム名
882         */
883        public void setNoDisplay( final String columnName ) {
884                setBooleanArray( columnName,false,clmDisplay );
885        }
886
887        /**
888         * 同一表示データをまとめる(表示しない)カラム名を、CSV形式で与えます。
889         *
890         * これは、カラムのグループ化指定を行います。
891         * 同じカラム番号で一つ上の行番号と同じ内容の場合に、表示しないというものです。
892         * 対応は、表示(Renderer)時のみとします。
893         * カラム単位なので、新しいゼブラによる色分けは行いません。(任意のカラムに適用できる為)
894         * また、ファイル出力などのデータ自身は変更されていませんので、そのままデータが落ちます。
895         * また、全カラムについて、有効にする場合は、group="*" を設定します。
896         *
897         * @og.rev 3.8.5.0 (2006/03/20) 新規追加
898         * @og.rev 5.1.8.0 (2010/07/01) 内部ロジック変更(setBooleanArray)
899         *
900         * @param       group まとめるカラム名(CSV形式)
901         */
902        public void setColumnGroup( final String group ) {
903                if( group != null ) {
904                        if( groupType == null ) { groupType = CLM_GRP.KIGO ; }
905                        setBooleanArray( group,true,clmGroup );
906                }
907        }
908
909        /**
910         * 同一表示データをまとめないカラム名を、CSV形式で与えます。
911         *
912         * これは、カラムのグループ化指定で、同一でもまとめないカラムを指定するほうが簡単な場合に
913         * 使用します。例えば、キー情報以外は、グループ化指定したい場合などに便利です。
914         * 動作は、columnGroup の動きと同じです。(まとめないカラムを指定するだけです。)
915         *
916         * これは、同一表示データをまとめるカラム名の指定(columnGroup)と同時にセットする
917         * ことは出来ません。
918         * また、全カラムについて、有効にする場合は、group="*" を設定します。
919         *
920         * @og.rev 5.1.8.0 (2010/07/01) 新規追加
921         *
922         * @param       group まとめるカラム名(CSV形式)
923         */
924        public void setNoGroup( final String group ) {
925                if( group != null ) {
926                        if( groupType == null ) { groupType = CLM_GRP.KIGO ; }
927                        setBooleanArray( group,false,clmGroup );
928                }
929        }
930
931        /**
932         * 同一表示データをまとめる場合の、表示方法を指定します。
933         *
934         * これは、カラムのグループ化指定(columnGroup)を行う場合の、まとめ表示の方法を指定します。
935         * なにも指定しない場合は、まとめカラムは、表示しない(ゼロ文字列)になります。
936         * その場合、先の行と同じ場合も、変更されたカラムが、NULL(ゼロ文字列)であった場合も、
937         * 同じ用に表示されるため、区別が付きません。
938         * そこで、前の行と同じデータの場合に、特殊な処理を行うことで、区別できるようにします。
939         * 指定方法が特殊なので、注意が必要です。
940         *   記号の場合:
941         *       記号(-- , → , ↓ , * など)が指定された場合は、そのままの文字に置き換えられます。
942         *   アルファベットの場合:
943         *       アルファベット(a-z,A-Z)の場合は、&lt;span class="アルファベット"&gt;元の文字&lt;/span&gt;
944         * 例えば、バックカラーに色を付ける、文字を薄い灰色にする、などできます。
945         * ただし、データ量が圧倒的に増えるため、大量のデータ等で使用するのは避けたほうが良いと思います。
946         *
947         * @og.rev 3.8.5.0 (2006/03/20) 新規追加
948         * @og.rev 6.3.9.0 (2015/11/06) 判定条件の記述が間違っていた。
949         *
950         * @param       grpCls まとめ表示の方法
951         */
952        public void setGroupClass( final String grpCls ) {
953                if( grpCls != null ) {
954                        groupClass = grpCls ;
955                        if( groupClass.isEmpty() ) {    // ゼロ文字列の場合
956                                groupType = CLM_GRP.KIGO ;
957                        }
958                        else {
959                                final char ch = groupClass.charAt(0);
960                                if( ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' ) {        // 6.3.9.0 (2015/11/06)         6.9.7.0 (2018/05/14) PMD Useless parentheses.
961                                        groupType = CLM_GRP.CHAR ;
962                                }
963                                else {
964                                        groupType = CLM_GRP.KIGO ;
965                                }
966                        }
967                }
968        }
969
970        /**
971         * 同一表示データをまとめる場合に、行(row)か列(column)を指定します(初期値:false:ROW)
972         *
973         * これは、カラムのグループ化指定(columnGroup)を行う場合の、まとめ表示の方向を指定します。
974         * ROW(初期値:false)を指定すると、指定のカラムで、行単位に同一データかどうかを判定します。
975         * COLUMN(true)を指定すると、columnGroup で指定した順番に、列方向に同一データかどうかを判定します。
976         * DBTableModelの登録順で、ひとつ前のカラムと比較します。
977         *
978         * @og.rev 6.7.3.0 (2017/01/27) 新規追加
979         *
980         * @param       dir まとめ表示の方向(false:ROW/true:COLUMN)
981         * @see         #setColumnGroup( String )
982         */
983        public void setGroupDir( final boolean dir ) {
984                useGroupDir = dir;
985        }
986
987        /**
988         * カラム名リンクソートを表示するカラム名を、CSV形式で与えます。
989         *
990         * ヘッダーにソート用リンクを作成する useTableSorter 属性 に対して、
991         * カラム個別に作成する場合のカラム名をCSV形式で指定します。
992         * この tableSorterKeys 属性は、useTableSorter 属性 と無関係に、指定した
993         * カラムのみ、リンクを表示します。
994         * また、全カラムについて、有効にする場合は、columnName="*" を設定します。
995         * 例:"OYA,KO,HJO,SU,DYSET,DYUPD"
996         *
997         * @og.rev 3.6.0.0 (2004/09/17) 新規作成
998         * @og.rev 5.1.8.0 (2010/07/01) 内部ロジック変更(setBooleanArray)
999         *
1000         * @param       columnName      カラム名
1001         */
1002        public void setTableSorterKeys( final String columnName ) {
1003                if( columnName != null ) {
1004                        setBooleanArray( columnName,true,sortKeys );
1005
1006                        useSorterKeys = true;                           // 使用したことを記憶
1007                }
1008        }
1009
1010        /**
1011         * 各カラムのフィールドのデータ長を返します。
1012         *
1013         * @og.rev 3.5.5.5 (2004/04/23) DBColumn の size と maxlength の 意味を変更
1014         *
1015         * @param       column カラム番号
1016         *
1017         * @return      カラム数
1018         */
1019        protected int getColumnSize( final int column ) {
1020                return dbColumn[column].getTotalSize(); // 4.0.0 (2005/01/31) メソッド名変更
1021        }
1022
1023        /**
1024         * カラム数を返します。
1025         *
1026         * @return      カラム数
1027         */
1028        protected int getColumnCount() {
1029                return columnCount ;
1030        }
1031
1032        /**
1033         * 行数を返します。
1034         *
1035         * @return      行数
1036         */
1037        protected int getRowCount() {
1038                return rowCount;
1039        }
1040
1041        /**
1042         * リストボックスを作成する場合の name をセットします。
1043         *
1044         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
1045         *
1046         * @param  name 属性
1047         */
1048        protected void setName( final String name ) {
1049                this.name = name;
1050        }
1051
1052        /**
1053         * リストボックスを作成する場合の name を返します。
1054         *
1055         * @return      name属性
1056         */
1057        protected String getName() {
1058                return name;
1059        }
1060
1061        /**
1062         * カラム名をもとに、そのカラム番号を返します。
1063         * カラム名が存在しない場合は、 HybsSystemException を throw します。
1064         *
1065         * @param       columnName       カラム名
1066         *
1067         * @return      カラム番号
1068         */
1069        protected int getColumnNo( final String columnName ) {
1070                return table.getColumnNo( columnName );
1071        }
1072
1073        /**
1074         * 表示開始位置を返します。
1075         *
1076         * @return      表示開始位置
1077         */
1078        public int getStartNo() {
1079                return startNo;
1080        }
1081
1082        /**
1083         * 表示開始位置をセットします。
1084         *
1085         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
1086         *
1087         * @param  no    表示開始位置
1088         */
1089        public void setStartNo( final int no ) {
1090                if( no >= 0 ) { startNo = no; }
1091        }
1092
1093        /**
1094         * 先頭へ戻るリンク間隔を返します。
1095         *
1096         * @return      backLinkCount    リンク間隔
1097         */
1098        public int getBackLinkCount() {
1099                return backLinkCount;
1100        }
1101
1102        /**
1103         * 先頭へ戻るリンク間隔をセットします。
1104         *
1105         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
1106         *
1107         * @param  no   リンク間隔
1108         */
1109        public void setBackLinkCount( final int no ) {
1110                if( no >= 0 ) { backLinkCount = no; }
1111        }
1112
1113        /**
1114         * ヘッダーを出力する間隔を取得します。
1115         *
1116         * @og.rev 3.5.2.0 (2003/10/20) 新規作成
1117         *
1118         * @return      ヘッダーの表示間隔 ( 0:通常ヘッダ、n:n回ごとに現れる )
1119         */
1120        public int getHeaderSkipCount() {
1121                return headerSkipCount;
1122        }
1123
1124        /**
1125         * ヘッダーを出力する間隔をセットします。
1126         *
1127         * 0を指定すると、繰り返しません(つまり、ヘッダーを最初に表示するだけです。)
1128         * 数字を指定すると、その回数毎に、ヘッダーをデータの行に挿入します。
1129         *
1130         * @og.rev 3.5.2.0 (2003/10/20) 新規作成
1131         *
1132         * @param       hsc ヘッダーの表示間隔 ( 0:通常ヘッダ、n:n回ごとに現れる )
1133         */
1134        public void setHeaderSkipCount( final int hsc ) {
1135                headerSkipCount = hsc;
1136        }
1137
1138        /**
1139         * 表示件数を取得します。
1140         *
1141         * @return      表示件数
1142         */
1143        public int getPageSize() {
1144                return pageSize;
1145        }
1146
1147        /**
1148         * 表示件数をセットします。
1149         *
1150         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
1151         *
1152         * @param       psize 表示件数
1153         */
1154        public void setPageSize( final int psize ) {
1155                if( psize > 0 ) { pageSize = psize; }
1156        }
1157
1158        /**
1159         * フォーマットを設定します。
1160         * ※ このクラスでは実装されていません。
1161         *
1162         * @og.rev 3.5.4.0 (2003/11/25) 新規作成
1163         * @param list TableFormatterのリスト
1164         */
1165        public void setFormatterList( final List<TableFormatter> list ) {               // 4.3.3.6 (2008/11/15) Generics警告対応
1166                final String errMsg = "このメソッドは、フォーマット関係のビューでのみ使用できます。";
1167                throw new UnsupportedOperationException( errMsg );
1168        }
1169
1170        /**
1171         * TableFormatterのタイプ値に対応した値を返します。
1172         *
1173         * タイプ値は、(#,$,!) が指定可能です。
1174         * rowが、-1 の場合は、getSortedColumnLabel(col) を返します。
1175         *
1176         * TableFormatterのタイプ別に値を返します。
1177         *   '#'      : getColumnLabel(loc)
1178         *   '$'      : getRendererValue(row,loc)
1179         *   '!'      : getValue(row,loc)
1180         *   それ以外 : getValueLabel(row,loc)/getSortedColumnLabel(loc)
1181         *
1182         * @og.rev 6.4.4.2 (2016/04/01) TableFormatterのタイプ別値取得
1183         *
1184         * @param type  TableFormatterのタイプ
1185         * @param row    データを取得する行番号
1186         * @param col    データを取得する列番号
1187         * @return タイプ別の値
1188         */
1189        protected String getTypeCaseValue( final char type , final int row , final int col ) {
1190                final String rtn ;
1191
1192                if( row < 0 ) {
1193                        switch( type ) {
1194                                case '#' : rtn = getColumnLabel(col);           break;
1195                                case '$' : rtn = getRendererValue(0,col);       break;
1196                                case '!' : rtn = getValue(0,col);                       break;
1197                                default  : rtn = getSortedColumnLabel(col);     break;          // row が負の場合
1198                        }
1199                }
1200                else {
1201                        switch( type ) {
1202                                case '#' : rtn = getColumnLabel(col);           break;
1203                                case '$' : rtn = getRendererValue(row,col);     break;
1204                                case '!' : rtn = getValue(row,col);                     break;
1205                                default  : rtn = getValueLabel(row,col);        break;          //
1206                        }
1207                }
1208
1209                return rtn;
1210        }
1211
1212        /**
1213         * 表示時の選択用オブジェクトのタイプを指定します。
1214         * ・複数選択可能時は "checkbox" を指定します。
1215         * ・一つだけ選ばせる場合は, "radio" を指定します。
1216         * ・隠しフィールドで全件を選ぶ場合は、"hidden" を指定します。
1217         * ・行番号に関する情報を出さない場合は、"none" を指定します(行番号は表示します)。
1218         * 初期値は、"checkbox" です。
1219         *
1220         * @og.rev 2.2.0.0 (2002/12/17) 選択用オブジェクトのタイプとして"hidden" を追加
1221         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
1222         * @og.rev 3.5.1.0 (2003/10/03) displayNumber 廃止。numberType 新規追加。
1223         *
1224         * @param       type 選択用オブジェクトのタイプ( "checkbox"/"radio"/"hidden"/"null" )
1225         */
1226        public void setSelectedType( final String type ) {
1227                if( type != null ) {
1228                        if( "checkbox".equalsIgnoreCase( type  ) ||
1229                                "radio".equalsIgnoreCase( type  ) ||
1230                                "hidden".equalsIgnoreCase( type ) ) {
1231                                        selectedType = type;
1232                        }
1233                        else {
1234                                selectedType = null;
1235                        }
1236                }
1237        }
1238
1239        /**
1240         * 表示時の行番号の表示方法を指定します。
1241         * ・sequenceは、1から始まる連番です。
1242         * ・none を指定すると、番号は表示されません。
1243         * ・delete を指定すると、行番号表示そのもののタグを取り除きます。(3.5.5.0 追加)
1244         * ・skip=カラム名を指定すると、そのカラムの値が NULL の場合は、番号をスキップします。
1245         * ・view=カラム名を指定すると、そのカラムの値が、使用されます。(ラベルは付きません)
1246         * skip=XX と、view=XX は、=の前後にスペースを入れないで下さい。
1247         * 初期値は、"sequence" です。
1248         *
1249         * @og.rev 3.5.1.0 (2003/10/03) 新規作成
1250         * @og.rev 3.5.5.0 (2004/03/12) numberType 属性の "delete" 値追加に伴なう、numberDisplay 変数の追加。
1251         * @og.rev 5.3.0.0 (2010/12/01) 左右分割スクロール(SplitViewTag)対応。numberType 再設定時のnumberDisplay初期化
1252         *
1253         * @param       type 行番号の表示方法のタイプ( /sequence/none/delete/skip=カラム名/view=カラム名/ )
1254         */
1255        public void setNumberType( final String type ) {
1256
1257                numberType = type ;
1258                numberDisplay = true;   // 5.3.0.0 (2010/12/01) numberType 再設定時のnumberDisplay初期化
1259                if( type != null && !type.startsWith( "seq" ) && !type.startsWith( "none" ) ) {
1260                        if( type.startsWith( "skip=" ) ) {
1261                                numberTypeClm = table.getColumnNo( type.substring( 5 ) );
1262                                numberTypeData = new String[rowCount];
1263                                int cnt = 1;
1264                                for( int i=0; i<rowCount; i++ ) {
1265                                        final String tmp = table.getValue( i,numberTypeClm );
1266                                        if( tmp != null && tmp.length() > 0 ) {
1267                                                numberTypeData[i] = String.valueOf( cnt );
1268                                                cnt++ ;
1269                                        }
1270                                        else {
1271                                                numberTypeData[i] = "" ;
1272                                        }
1273                                }
1274                        }
1275                        else if( type.startsWith( "view=" ) ) {
1276                                numberTypeClm = getColumnNo( type.substring( 5 ) );
1277                        }
1278                        // 3.5.5.0 (2004/03/12)
1279                        else if( type.startsWith( "delete" ) ) {
1280                                numberDisplay = false;
1281                        }
1282                        else {
1283                                // 3.5.5.0 (2004/03/12) 不正な値をエラーチェック
1284                                final String errMsg = "numberType属性の値が不正です。numberType=[" + numberType + "]" +
1285                                                CR +
1286                                                "設定できるのは、sequence/none/delete/skip=カラム名/view=カラム名/ です。";
1287                                throw new HybsSystemException( errMsg );
1288                        }
1289                }
1290        }
1291
1292        /**
1293         * 表示時の選択用オブジェクトのタイプを返します。
1294         * 複数選択可能時は "checkbox"  一つだけ選ばせる場合は, "radio" を指定します。
1295         * 初期値は、"checkbox" です。
1296         * "checkbox"/"radio"/"hidden" 以外の文字列の場合は, null を返します。
1297         *
1298         * @return       選択用オブジェクトのタイプ( "checkbox"/"radio"/"hidden"/"null" )
1299         */
1300        protected String getSelectedType() {
1301                return selectedType ;
1302        }
1303
1304        /**
1305         * No カラムの文字列を取得します。
1306         * setNumberType で指定した、(sequence / none / skip=カラム名 / view=カラム名)に
1307         * 応じた値(レンデラーの値)を返します。
1308         *
1309         * @og.rev 3.5.1.0 (2003/10/03) 新規作成
1310         *
1311         * @param   row 行番号
1312         *
1313         * @return      Noカラムの文字列
1314         */
1315        protected String getNumberData( final int row ) {
1316                String rtn = null;
1317
1318                if( numberType == null || numberType.startsWith( "se" ) ) {     // sequence
1319                        rtn = String.valueOf( row + 1 );
1320                }
1321                else {
1322                        if( numberType.startsWith( "no" ) ) {                   // none
1323                                rtn = "";
1324                        }
1325                        else if( numberType.startsWith( "vi" ) ) {              // view
1326                                rtn = getRendererValue( row,numberTypeClm );
1327                        }
1328                        else if( numberType.startsWith( "sk" ) ) {              // skip
1329                                rtn = numberTypeData[row];
1330                        }
1331                }
1332
1333                return rtn ;
1334        }
1335
1336        /**
1337         * No カラムのヘッダー文字列を取得します。
1338         * setNumberType で指定した、(sequence / none / skip=カラム名 / view=カラム名)に
1339         * 応じた値(ラベル)を返します。
1340         * 具体的には、none 以外は、"No" という文字を、none の時は、""(ゼロストリング)を返します。
1341         *
1342         * @og.rev 3.5.4.6 (2004/01/30) 新規作成
1343         *
1344         * @return       Noカラムのヘッダー文字列
1345         */
1346        protected String getNumberHeader() {
1347                String rtn = NO_HEADER;
1348
1349                if( numberType.startsWith( "no" ) ) {                   // none
1350                        rtn = "";
1351                }
1352
1353                return rtn ;
1354        }
1355
1356        /**
1357         * テーブル等のチェックボックスに属性を付加します
1358         * JavaScript などの HTML基本タグ以外の属性を、そのまま
1359         * チェックボックス/ラジオボタン等に使用します。
1360         *
1361         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
1362         *
1363         * @param       option オプション属性文字列
1364         */
1365        public void setOptionTypeAttributes( final String option ) {
1366                optTypeAttri = option;
1367        }
1368
1369        /**
1370         * テーブル等のチェックボックスに属性を付加します
1371         * JavaScript などの HTML基本タグ以外の属性を、そのまま
1372         * チェックボックス/ラジオボタン等に使用します。
1373         *
1374         * @return      オプション属性
1375         */
1376        protected String getOptionTypeAttributes() {
1377                return optTypeAttri ;
1378        }
1379
1380        /**
1381         * 最終表示番号を取得します。
1382         * 最終表示番号は、表示開始位置 + 表示件数 で求まります。
1383         * lastNo = startNo +  pageSize;
1384         *
1385         * ただし、最終表示番号 > データ件数 の場合は、 最終表示番号 = データ件数
1386         * とします。
1387         * なお、表示件数 が -1 の場合は、デフォルトの表示件数を使用します。
1388         *
1389         * @param       startNo    表示開始位置
1390         * @param       pageSize   表示件数
1391         *
1392         * @return      最終表示番号
1393         */
1394        protected int getLastNo( final int startNo, final int pageSize ) {
1395                int lastNo = startNo + ( pageSize < 0 ? getPageSize() : pageSize );
1396                if( lastNo > rowCount ) {
1397                        lastNo = rowCount ;
1398                }
1399
1400                if( rowCount < 0 || startNo < 0 || lastNo < 0 ) {
1401                        final String errMsg = "startNo lastNo の範囲が不正です。" + CR
1402                                                + " startNo=" + startNo + " , lastNo=" + lastNo + " , RowCount=" + rowCount;
1403                        throw new HybsSystemException( errMsg );
1404                }
1405
1406                return lastNo ;
1407        }
1408
1409        /**
1410         * ビューフォームのタイプを返します。
1411         * これは、ViewFormFactory で、org.opengion.hayabusa.html.ViewForm_ + 『type』
1412         * で作成されるサブクラスの 『type』 部分を返します。
1413         *
1414         * @og.rev 3.5.4.3 (2004/01/05) viewFormID を使用するように変更します。
1415         *
1416         * @return      ビューフォームのタイプ
1417         */
1418        public String getViewFormType() {
1419                return viewFormID ;
1420        }
1421
1422        /**
1423         * ビューリンクオブジェクトを設定します。
1424         * これは、ViewLink タグで作成された キー(カラム名)とリンク文字列を
1425         * 持っている Attributes オブジェクトを受け取り、内部でリンク表示に
1426         * 使用します。
1427         *
1428         * @og.rev 3.5.6.4 (2004/07/16) table が null の場合は、セットしません。
1429         *
1430         * @param       link    ビューリンクオブジェクト
1431         */
1432        public void setViewLink( final ViewMarker link ) {
1433                viewLink = link;
1434                if( viewLink != null && table != null ) {
1435                        viewLink.setDBTableModel( table ) ;
1436                }
1437        }
1438
1439        /**
1440         * ビューマーカーオブジェクトを設定します。
1441         * これは、ViewMarker タグで作成された キー(カラム名)とマーカー文字列を
1442         * 持っている Attributes オブジェクトを受け取り、内部でマーカー表示に
1443         * 使用します。
1444         *
1445         * @og.rev 3.5.6.4 (2004/07/16) table が null の場合は、セットしません。
1446         *
1447         * @param       marker  ビューマーカーオブジェクト
1448         */
1449        public void setViewMarker( final ViewMarker marker ) {
1450                viewMarker = marker;
1451                if( viewMarker != null && table != null ) {
1452                        viewMarker.setDBTableModel( table ) ;
1453                }
1454        }
1455
1456        /**
1457         * 編集マーカーオブジェクトを設定します。
1458         * これは、ViewMarker タグで、isRendere="false" で作成された 編集キー(カラム名)と
1459         * マーカー文字列を持っている Attributes オブジェクトを受け取り、内部でマーカー表示に
1460         * 使用します。
1461         *
1462         * @og.rev 3.8.6.1 (2006/10/20) 新規追加
1463         *
1464         * @param       marker  ビューマーカーオブジェクト
1465         */
1466        public void setEditMarker( final ViewMarker marker ) {
1467                editMarker = marker;
1468                if( editMarker != null && table != null ) {
1469                        editMarker.setDBTableModel( table ) ;
1470                }
1471        }
1472
1473        /**
1474         * 検索結果メッセージを表示する/しないを設定します
1475         * 初期値は、表示する(false)です。
1476         *
1477         * @param       noMessage [true:表示しない/false:表示する]
1478         */
1479        public void setNoMessage( final boolean noMessage ) {
1480                this.noMessage = noMessage;
1481        }
1482
1483        /**
1484         * DBColumn オブジェクトを返します。
1485         *
1486         * @og.rev 3.1.8.0 (2003/05/16) DBColumn オブジェクト取得用のメソッド追加
1487         *
1488         * @param       column カラム番号
1489         *
1490         * @return  DBColumnオブジェクト
1491         */
1492        protected DBColumn getDBColumn( final int column ) {
1493                return dbColumn[column];
1494        }
1495
1496        /**
1497         * カラム(列)にカラムオブジェクトを割り当てます。
1498         * カラムオブジェクトは,ラベルやネームなど,そのカラム情報を
1499         * 保持したオブジェクトです。
1500         *
1501         * @og.rev 5.6.2.3 (2013/03/22) 新規追加
1502         *
1503         * @param   column  カラムオブジェクト
1504         * @param   clm       ヘッダーを適応するカラム(列)
1505         */
1506        protected void setDBColumn( final int column, final DBColumn clm ) {
1507                dbColumn[column] = clm;
1508        }
1509
1510        /**
1511         * チェックの入った行のみを表示させるかどうか指定します。
1512         *
1513         * "true" で、チェックの入った行のみを表示させます。
1514         * 従来は、TextField系のViewに対して、NEXT,PREVでチェックの
1515         * 入った行のみを表示させる機能でしたが、Table系のViewに対しても、
1516         * 同様に機能するように、しました。
1517         * 初期値は、ViewForm.DEFAULT_SKIP です。
1518         *
1519         * @og.rev 3.5.3.1 (2003/10/31) 新規追加
1520         *
1521         * @param       skp チェックの入った行のみを表示させるかどうか(true:のみ表示/false:前件表示)
1522         */
1523        public void setSkip( final boolean skp ) {
1524                skip = skp;
1525        }
1526
1527        /**
1528         * チェックの入った行のみを表示させるかどうか(スキップするかどうか)を返します。
1529         *
1530         * skip=true で、かつ、チェックの入っていない行の場合に、trueを返します。
1531         * つまり、skip=trueの場合は、チェックの入っていない行は、スキップするという
1532         * 判断を行います。
1533         * skip属性の初期値は、ViewForm.DEFAULT_SKIP です。
1534         *
1535         * @og.rev 3.5.3.1 (2003/10/31) 新規追加
1536         *
1537         * @param       row     行番号
1538         *
1539         * @return      スキップする(true)/スキップしない(false)
1540         */
1541        protected boolean isSkip( final int row ) {
1542                return skip && ! isChecked( row );
1543        }
1544
1545        /**
1546         * チェックボックスの全チェックを選択するJavaScript の機能を使用するかどうかを指定します。
1547         *
1548         * 1 で、コントロール用のチェックボックスが現れて、この機能を使用することができるようになります。
1549         * 0 は、従来どおりです。
1550         * 使用するにあたり、jsp/commpn/default.js にJavaScriptを設定しておきます。(設定済み)
1551//       * 初期値は、システムパラメータ の VIEW_USE_CHECK_CONTROL です。(0:使用しない)
1552         *
1553         * @og.rev 3.5.4.3 (2004/01/05) 新規追加
1554         * @og.rev 3.7.0.1 (2005/01/31) 全件チェックコントロール変更( boolean ⇒ int )
1555         *
1556         * @param       chCtrl チェックボックスの全チェックを選択する機能を使用するかどうか
1557         *                      (1:使用する/0:使用しない/2:初期値チェック済み)
1558         */
1559        public void setUseCheckControl( final int chCtrl ) {
1560                useCheckControl = chCtrl;
1561        }
1562
1563        /**
1564         * チェックボックスの全チェックを選択するJavaScript の機能を使用するかどうかを返します。
1565         *
1566         * 内部的には、(1:使用する/0:使用しない/2:初期値チェック済み)の値を保持していますが、
1567         * タグを作成する場合には、まず、使用するかどうかを指定する必要があるため、
1568         * 1:使用する/2:初期値チェック済み は、true:使用する、0 は、false:使用しない
1569         * を返します。
1570         *
1571         * @og.rev 3.5.4.3 (2004/01/05) 新規追加
1572         *
1573         * @return      チェックボックスの全チェックを選択する機能を使用するかどうか(true:使用する/false:使用しない)
1574         */
1575        protected boolean isUseCheckControl() {
1576                return useCheckControl > 0;
1577        }
1578
1579        /**
1580         * チェックボックスの全チェックを選択する タグ文字列を返します。
1581         *
1582         * 内部的には、(1:使用する/0:使用しない/2:初期値チェック済み)の値を
1583         * 保持していますので、それに対応した文字列を返します。
1584         *
1585         * @og.rev 3.7.0.1 (2005/01/31) 新規追加
1586         * @og.rev 5.1.8.0 (2010/07/01) 全チェックを押した状態で画面遷移した場合にチェック状態を保持する。
1587         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。
1588         *
1589         * @return      チェックボックスの全チェックを選択する機能を使用するかどうか
1590         *                      (1:使用する/0:使用しない/2:初期値チェック済み)
1591         */
1592        protected String getAllCheckControl() {
1593                final String rtn;
1594                switch( useCheckControl ) {
1595//                      case 1: rtn = "<input type=\"checkbox\" name=\"ALL_CHECK\" value=\"2\" onClick=\"checkbox(this);\" />" ;
1596                        case 1: rtn = "<input type=\"checkbox\" name=\"ALL_CHECK\" value=\"2\" onClick=\"checkbox(this);\" >" ;
1597                                        break;
1598//                      case 2: rtn = "<input type=\"checkbox\" name=\"ALL_CHECK\" value=\"2\" onClick=\"checkbox(this);\" checked=\"checked\" />" ;
1599                        case 2: rtn = "<input type=\"checkbox\" name=\"ALL_CHECK\" value=\"2\" onClick=\"checkbox(this);\" checked=\"checked\" >" ;
1600                                        break;
1601                        default : rtn = "" ;
1602                                        break;          // 6.0.2.5 (2014/10/31) break追記
1603                }
1604                return rtn ;
1605        }
1606
1607        /**
1608         * ヘッダーにソート用リンクを作成するかどうかを指定します。
1609         *
1610         * "true" で、ヘッダーにソート用リンクを作成します。
1611         * false は、作成しません。
1612         *
1613         * @og.rev 3.5.4.7 (2004/02/06) 新規追加
1614         *
1615         * @param       flag ヘッダーにソート用リンクを作成するかどうか(true:作成する/false:作成しない)
1616         */
1617        public void setUseTableSorter( final boolean flag ) {
1618                useTableSorter = flag;
1619        }
1620
1621        /**
1622         * ヘッダーにソート用リンクを作成する時の、リクエスト引数のMapを設定します。
1623         *
1624         * ソート用URLに、リクエスト時の引数を設定する必要があります。
1625         * そのため、リクエスト時のキーと値のセットをMapで指定します。
1626         * このMap は、リクエストキャッシュより取り出します。
1627         * 実装では、このMapを元に、URLのQuery部文字列を作成します。処理過程において、
1628         * このMap を書き換えることは行いません。
1629         *
1630         * @og.rev 3.6.0.0 (2004/09/17) 新規作成
1631         * @og.rev 3.6.0.0 (2004/09/22) 引数が null の時の処理追加
1632         * @og.rev 4.0.0.0 (2005/01/31) Map.keySet より Map.entrySet を使用するように変更
1633         * @og.rev 5.10.1.1 (2018/07/13) keyのマルチバイト文字エンコード対応
1634         *
1635         * @param       map ヘッダーソート時のリンクに追加するリクエスト変数のキャッシュMap
1636         */
1637        public void makeTableSorterQuery( final Map<?,?> map ) {                                // 4.3.3.6 (2008/11/15) Generics警告対応
1638                if( map == null ) { return; }                                                                           // 3.6.0.0 (2004/09/22)
1639
1640                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
1641                final Iterator<?> ite = map.entrySet().iterator() ;                                                     // 4.0.0 (2005/01/31)
1642                while( ite.hasNext() ) {
1643                        final Map.Entry<?,?> entry = (Map.Entry<?,?>)ite.next();                                // 4.3.3.6 (2008/11/15) Generics警告対応
1644                        final String key = (String)entry.getKey();
1645                        if( key != null
1646                                         &&     ! key.equalsIgnoreCase( "command" )
1647                                         &&     ! key.equalsIgnoreCase( HybsSystem.SORT_COLUMNS ) ) {
1648                                final String[] vals = (String[])entry.getValue();                                       // 4.0.0 (2005/01/31)
1649                                if( vals != null ) {
1650                                        for( int i=0; i<vals.length; i++ ) {
1651//                                              buf.append( '&' ).append( key ).append( '=' );                          // 6.0.2.5 (2014/10/31) char を append する。
1652                                                buf.append( '&' ).append( StringUtil.urlEncode( key ) ).append( '=' )   // 5.10.1.1 (2018/07/13)
1653                                                        .append( StringUtil.urlEncode( vals[i] ) );
1654                                        }
1655                                }
1656                        }
1657                }
1658
1659                if( buf.length() > 0 ) {
1660                        sorterQuery = buf.toString();
1661                }
1662        }
1663
1664        /**
1665         * カラムソート機能(リンク)の付いたラベル名を返します。
1666         * カラムの項目名に対して,見える形の文字列を返します。
1667         * 一般には,リソースバンドルと組合せて,各国ロケール毎にラベルを
1668         * 切替えます。
1669         *
1670         * @og.rev 3.5.4.7 (2004/02/06) 新規追加
1671         * @og.rev 3.6.0.0 (2004/09/17) sortKeys の使用によるカラム個別のリンク有無追加
1672         * @og.rev 5.2.1.0 (2010/10/01) 一括入力カラムのアシスト機能を利用する場合の処理を追加
1673         * @og.rev 5.2.3.0 (2010/12/01) チェックボックスでは、onChange ではなく、onClick でイベントを発生させます。
1674         * @og.rev 5.6.9.1 (2013/10/11) カラム長にカンマが入った場合の対応
1675         * @og.rev 5.7.8.1 (2014/07/18) カラム長が 1000 では、少ない為。(HTML5ではエラーになる為)
1676         * @og.rev 6.0.2.0 (2014/09/19) Bulkset エラー回避
1677         * @og.rev 6.1.1.0 (2015/01/17) Bulkset関係( ViewLength を使用、左寄せ、SLABEL設定 )
1678         * @og.rev 6.2.0.0 (2015/02/27) class="W100" を追加することで、テーブル幅いっぱいの入力枠にする。
1679         * @og.rev 6.2.1.0 (2015/03/13) 動的カラム(COLUMN)は、TEXT に置き換える。
1680         * @og.rev 6.2.2.2 (2015/04/03) NO_MAXLEN キーの値が、"true" の場合、maxlength を強制削除する。
1681         * @og.rev 6.2.2.4 (2015/04/24) class="W100"の追加条件に、dbType 制限をかけます。
1682         * @og.rev 5.9.23.0 (2017/08/10) useSorterKeysが無い場合でもspanは外側に付ける
1683         * @og.rev 6.8.1.4 (2017/08/25) must の取り消し。これは、config.setEditorAttributes( attri ); の副作用で、config から、must をremoveする必要が出てきました。
1684         * @og.rev 6.9.9.2 (2018/09/18) ソートキーのマルチバイト文字エンコード対応
1685         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。
1686         *
1687         * @param       column カラム番号
1688         *
1689         * @return      ソート機能(リンク)の付いたラベル名
1690         */
1691        protected String getSortedColumnLabel( final int column ) {
1692                // 6.4.2.1 (2016/02/05) PMD refactoring. Prefer StringBuffer over += for concatenating strings
1693                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
1694
1695                final String clmLbl = getColumnLabel( column ) ;
1696
1697                if( useSorterKeys && sortKeys[column] || ! useSorterKeys && useTableSorter ) {  // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
1698                        rtn.append( "<a href=\"?command=VIEW&" )
1699                                .append( HybsSystem.SORT_COLUMNS ).append( '=' )
1700        //                      .append( dbColumn[column].getName() )
1701                                .append( StringUtil.urlEncode( dbColumn[column].getName() ) )                   // 6.9.9.2 (2018/09/18) ソートキーのマルチバイト文字エンコード対応
1702                                .append( sorterQuery ).append( "\">" )
1703                                .append( clmLbl ).append( "</a>" );
1704                }
1705                else {
1706                        rtn.append( "<span>" ).append( clmLbl ).append( "</span>" );    // 5.9.23.0 (2017/08/10)
1707                }
1708
1709                // 5.2.1.0 (2010/10/01) 一括入力カラムのアシスト機能対応(bulkSet)
1710                if( isClmBulkSet( column ) ) {
1711                        final DBColumnConfig config = dbColumn[column].getConfig();
1712                        config.setAddNoValue( true );
1713                        // 6.2.2.2 (2015/04/03) NO_MAXLEN キーの値が、"true" の場合、maxlength を強制削除する。
1714                        final String editor = config.getEditor();
1715                        if( "RADIO".equals( editor ) ) {                        // 6.2.2.2 (2015/04/03)
1716                                config.setEditor( "MENU" );
1717                        }
1718                        // 6.2.1.0 (2015/03/13) 動的カラム(COLUMN)は、TEXT に置き換える。
1719                        else if( "COLUMN".equals( editor ) ) {          // 6.2.2.2 (2015/04/03)
1720                                config.setEditor( "TEXT" );
1721                        }
1722
1723                        final Attributes attri = new Attributes();
1724                        // 5.2.3.0 (2010/12/01) チェックボックスでは、onChange ではなく、onClick でイベントを発生させます。
1725                        if( "CHBOX".equals( editor ) ) {                        // 6.2.2.2 (2015/04/03)
1726                                attri.add( "onClick",  "bulkSet(this);" );
1727                        }
1728                        else {
1729                                attri.add( "onChange",  "bulkSet(this);" );
1730                                attri.add( "ondblclick","bulkPaste(this);" );
1731                                // 6.2.2.2 (2015/04/03) NO_MAXLEN キーの値が、"true" の場合、maxlength を強制削除する。
1732                                attri.set( "NO_MAXLEN", "true" );                               // W100 と連動
1733                                attri.add( "style",             "float:left;" );                // 6.1.1.0 (2015/01/17) CHBOX以外は左寄せ
1734
1735        //                      // 6.2.2.4 (2015/04/24) class="W100"の追加条件に、dbType 制限をかけます。
1736                                final String dbType = "," + config.getDbType() + ",";
1737                                if( ",X,K,KX,XK,ALL,".contains( dbType ) ) {
1738                                        attri.add( "class", "W100" );                           // 6.2.0.0 (2015/02/27) テーブル幅いっぱいの入力枠にする。
1739                                        config.setFieldSize( "1" );                                     // 6.2.2.2 (2015/04/03) ここで設定しないと、後付けされる。
1740                                }
1741                        }
1742                        attri.add( "onkeydown", "ctrlCV(this);" );
1743
1744                        config.setEditorAttributes( attri );
1745                        config.removeEditorAttributes( "class" , "must" );      // 6.8.1.4 (2017/08/25) must の取り消し
1746                        config.setUseSLabel( "true" );                                          // 6.1.1.0 (2015/01/17) SLABEL設定。ほんとはMENU系のみでよい。
1747
1748                        final String key = config.getName();
1749                        config.setName( "h_" + key );
1750
1751                        final DBColumn clm = new DBColumn( config );
1752
1753                        // 6.0.2.0 (2014/09/19) Bulkset エラー回避
1754                        try {
1755                                // 6.4.2.1 (2016/02/05) PMD refactoring. Prefer StringBuffer over += for concatenating strings
1756//                              rtn.append( "<br />" ).append( clm.getEditorValue( null ) );    // 注意:検索用のEditorが呼ばれる。
1757                                rtn.append( "<br>" ).append( clm.getEditorValue( null ) );              // 注意:検索用のEditorが呼ばれる。
1758                        }
1759                        catch( final RuntimeException ex ) {
1760                                final String errMsg = "bulkSet でエラーが発生しました。" + CR
1761                                                        + " Label=" + rtn + " , Column=" + key + " , Editor=" + editor          // 6.2.2.2 (2015/04/03)
1762                                                        + CR
1763                                                        + ex.getMessage();
1764                                System.err.println( errMsg );
1765                        }
1766                }
1767
1768                return rtn.toString();                  // 6.4.2.1 (2016/02/05)
1769        }
1770
1771        /**
1772         * 指定カラムNoがmust指定されているかどうか。
1773         *
1774         * @og.rev 5.5.4.2 (2012/07/13)
1775         *
1776         * @param       column カラムNO
1777         * @return must指定されているかどうか[true:されている/false:されていない]
1778         */
1779        protected boolean isMustColumn( final int column){
1780                if( nullCheck != null && nullCheck.length > 0 ){
1781                        for( int i=0; i<nullCheck.length; i++ ){
1782                                if( nullCheck[i].equals( dbColumn[column].getName() ) ){
1783                                        return true;
1784                                }
1785                        }
1786                }
1787                return false;
1788        }
1789
1790        /**
1791         * 指定カラムNoがmustAny指定されているかどうか。
1792         *
1793         * @og.rev 5.5.4.2 (2012/07/13)
1794         *
1795         * @param       column カラムNO
1796         * @return mustAny指定されているかどうか[true:されている/false:されていない]
1797         */
1798        protected boolean isMustAnyColumn( final int column){
1799                if( mustAnyCheck != null && mustAnyCheck.length > 0 ){
1800                        for( int i=0; i<mustAnyCheck.length; i++ ){
1801                                if( mustAnyCheck[i].equals( dbColumn[column].getName() ) ){
1802                                        return true;
1803                                }
1804                        }
1805                }
1806                return false;
1807        }
1808
1809        /**
1810         * ViewForm のサブクラスに渡すパラメータマップを設定します。
1811         *
1812         * @og.rev 3.5.4.8 (2004/02/23) ViewParamTag のパラメータを追加します。
1813         * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。
1814         *
1815         * @param       map パラメータマップ
1816         */
1817        public void setParam( final ConcurrentMap<String,String> map ) {
1818                viewParam = map ;
1819        }
1820
1821        /**
1822         * ViewForm のサブクラスに渡すパラメータマップの値を返します。
1823         * パラメータが 存在しない(null)か、値が 存在しない(null)の場合は、
1824         * 初期値を返します。
1825         *
1826         * @og.rev 3.5.5.9 (2004/06/07) 新規追加
1827         *
1828         * @param       key     パラメータの取り出すキー
1829         * @param       def     パラメータが存在しない場合の初期値
1830         *
1831         * @return      パラメータ値
1832         */
1833        protected String getParam( final String key, final String def ) {
1834                if( viewParam == null ) { return def; }
1835                final String rtn = viewParam.get( key );                // 4.3.3.6 (2008/11/15) Generics警告対応
1836
1837                // 6.4.1.1 (2016/01/16) 条件反転
1838                return ( rtn == null ) ? def : rtn ;
1839        }
1840
1841        /**
1842         * ViewForm のサブクラスに渡すパラメータマップの値を返します。
1843         * パラメータは、初期値が設定されているものとし、そのまま、値を返します。
1844         *
1845         * @og.rev 5.5.5.6 (2012/08/31) 新規追加
1846         *
1847         * @param       key     パラメータの取り出すキー
1848         *
1849         * @return      パラメータ値
1850         */
1851        protected String getParam( final String key ) {
1852                return (viewParam == null) ? null : viewParam.get( key );
1853        }
1854
1855        /**
1856         * ViewForm のサブクラスに渡すパラメータマップの値を int で返します。
1857         * パラメータは、初期値が設定されているものとし、null の場合は、-1 を返します。
1858         *
1859         * @og.rev 5.5.5.6 (2012/08/31) 新規追加
1860         *
1861         * @param       key     パラメータの取り出すキー
1862         *
1863         * @return      パラメータ値(未設定時は、-1)
1864         */
1865        protected int getIntParam( final String key ) {
1866                final String rtn = (viewParam == null) ? null : viewParam.get( key );
1867                return (rtn == null) ? -1 : Integer.parseInt( rtn );
1868        }
1869
1870        /**
1871         * ViewForm のサブクラスに渡すパラメータマップの値を boolean で返します。
1872         * パラメータは、初期値が設定されているものとし、null の場合は、false を返します。
1873         *
1874         * @og.rev 5.5.5.6 (2012/08/31) 新規追加
1875         * @og.rev 6.3.9.1 (2015/11/27) 3項演算子を || or &amp;&amp; で簡素化できる(PMD)。
1876         *
1877         * @param       key     パラメータの取り出すキー
1878         *
1879         * @return      パラメータ値(未設定時は、false)
1880         */
1881        protected boolean getBoolParam( final String key ) {
1882                // 6.3.9.1 (2015/11/27) Boolean#parseBoolean(String) は、引数が null の場合、false を返す(引数のnullチェックは不要)。
1883                return viewParam != null && Boolean.parseBoolean( viewParam.get( key ) );
1884        }
1885
1886        /**
1887         * ViewForm のサブクラスに渡すパラメータ(文字列配列のArrayList)を設定します。
1888         *
1889         * @og.rev 5.5.8.3 (2012/11/17) ViewParamTag のパラメータを追加します。
1890         * @og.rev 5.5.9.0 (2012/12/03) ArrayListに変更
1891         *
1892         * @param       list 文字列配列のArrayList
1893         */
1894        public void setViewArrayList( final List<String[]> list ) {
1895                viewArrayList = list ;
1896        }
1897
1898        /**
1899         * ViewForm のサブクラスに渡すパラメータ(文字列配列のArrayList)の値を返します。
1900         * パラメータは、初期値が設定されているものとし、そのまま、値を返します。
1901         *
1902         * @og.rev 5.5.8.3 (2012/11/17) 新規追加
1903         * @og.rev 5.5.9.0 (2012/12/03) ArrayListに変更
1904         *
1905         * @return      パラメータ値
1906         */
1907        protected List<String[]> getViewArrayList() {
1908                return viewArrayList;
1909        }
1910
1911        /**
1912         * No 欄そのものを作成するかどうかを返します。
1913         *
1914         * numberType 属性に、"delete" という値を設定した場合は、No 欄そのものを
1915         * 作成しません。それ以外は、作成します。
1916         * 初期値は、作成する(true)です。
1917         *
1918         * @og.rev 3.5.5.0 (2004/03/12) 新規追加
1919         *
1920         * @return      No欄そのものを作成するかどうか(true:作成する/false:作成しない)
1921         */
1922        protected boolean isNumberDisplay() {
1923                return numberDisplay;
1924        }
1925
1926        /**
1927         * マーカーオブジェクト(リンク、マーカー)を設定します。
1928         * ここでは、旧 ViewForm 属性を 新ViewForm に直接セットします。
1929         *
1930         * @og.rev 3.5.6.1 (2004/06/25) 新規追加
1931         * @og.rev 3.8.6.1 (2006/10/20) editMarker 追加
1932         *
1933         * @param       view ViewFormオブジェクト
1934         */
1935        public void markerSet( final ViewForm view ) {
1936                if( view instanceof AbstractViewForm ) {
1937                        viewLink   = ((AbstractViewForm)view).viewLink ;
1938                        if( viewLink != null ) { viewLink.setDBTableModel( table ); }
1939                        viewMarker = ((AbstractViewForm)view).viewMarker;
1940                        if( viewMarker != null ) { viewMarker.setDBTableModel( table ); }
1941                        editMarker = ((AbstractViewForm)view).editMarker;
1942                        if( editMarker != null ) { editMarker.setDBTableModel( table ); }
1943                }
1944                else {
1945                        final String errMsg = "AbstractViewForm 以外の view は、サポートしていません。"
1946                                        + " view=[" + view + "]" ;
1947                        throw new HybsSystemException( errMsg );
1948                }
1949        }
1950
1951        /**
1952         * テーブルのバックグラウンドカラーの入れ替えのサイクルをセットします。
1953         * 0(ゼブラなし)、-1(ワーニング)、-2以下(エラー)、1(ゼブラ)、2以上(行数まとめ)
1954         * 初期値は、1(ゼブラ)です。
1955         *
1956         * @og.rev 3.5.6.2 (2004/07/05) ViewForm_HTMLTable より移動
1957         *
1958         * @param  sycle  0(ゼブラなし)、-1(ワーニング)、-2以下(エラー)、1(ゼブラ)、2以上(行数まとめ)
1959         */
1960        public void setBgColorCycle( final int sycle ) {
1961                bgColorCycle    = 1;            // 強制的に設定
1962
1963                if( sycle > 0 ) {                                               // 1(ゼブラ)、2以上(行数まとめ)
1964                        colorRow0               = BG_COLOR_ROW0 ;
1965                        colorRow1               = BG_COLOR_ROW1 ;
1966                        bgColorCycle    = sycle;                        // このケースのみ引数を設定
1967                }
1968                else if( sycle == -1 ) {                                        // -1(ワーニング)
1969                        colorRow0               = BG_WARNING_COLOR_ROW0 ;
1970                        colorRow1               = BG_WARNING_COLOR_ROW1 ;
1971                }
1972                else if( sycle < -1 ) {                                 // -2以下(エラー)
1973                        colorRow0               = BG_ERROR_COLOR_ROW0 ;
1974                        colorRow1               = BG_ERROR_COLOR_ROW1 ;
1975                }
1976                else {                                                                                  // 0(ゼブラなし)
1977                        colorRow0               = "" ;
1978                        colorRow1               = "" ;
1979                }
1980        }
1981
1982        /**
1983         * テーブルのバックグラウンドカラーのクラスに指定するカラム名を指定します。
1984         *
1985         * 通常のゼブラ模様は、tr 属性のクラス指定として、row_0、row_1 が指定されます。
1986         * その代わりに、ここで指定されたカラムの値がクラス属性として設定されます。
1987         * (指定するのはカラム名です。行単位にクラス属性の値を変えることが可能です。)
1988         * 選択行(row_sel)は、優先して使用されます。
1989         * 出力されるクラス名は、"row_" + 属性値 になります。
1990         *
1991         * @og.rev 5.1.8.0 (2010/07/01) 新規追加
1992         *
1993         * @param  clsClm ゼブラ模様の替わりに指定するクラスを格納したカラム名
1994         */
1995        public void setBgColorClsClm( final String clsClm ) {
1996                if( clsClm != null ) {
1997                        bgColorClsClmNo = table.getColumnNo( clsClm );
1998                }
1999        }
2000
2001        /**
2002         * テーブルのバックグラウンドカラーの値をセットします。
2003         * これは、DBTableModele が指定の行番号の時に、BG_COLOR_ROWSEL を
2004         * 返します。それ以外は、通常の getBgColorCycleClass( int )と
2005         * 同じ結果を返します。
2006         * BG_COLOR_ROWSEL の使用有無は、システムパラメータの
2007         * VIEW_USE_SELROW_COLOR 属性で指定できます。
2008         *
2009         * @og.rev 3.7.0.3 (2005/03/01) 新規追加
2010         * @og.rev 3.7.1.1 (2005/05/31) SEL_ROW機能使用時に、BG_COLOR_ROWSEL の使用 有/無を指定
2011         *
2012         * @param       indx 先頭からの連番( 0から始める )
2013         * @param       row 行番号
2014         *
2015         * @return      行の色を指定する class 属性( cssファイルで指定 )
2016         * @see #getBgColorCycleClass( int )
2017         */
2018        protected String getBgColorCycleClass( final int indx,final int row ) {
2019                return useSelRowColor && scrollRowNo == row ? BG_COLOR_ROWSEL : getBgColorCycleClass( indx ) ;          // 6.4.2.1 (2016/02/05) PMD refactoring. Useless parentheses.
2020        }
2021
2022        /**
2023         * テーブルのバックグラウンドカラーの値をセットします。
2024         * 行番号は, 0から始まるので、偶数を HTML_BG_COLOR_ROW0 、
2025         * 奇数行を HTML_BG_COLOR_ROW1 とします。
2026         * setBgColorCycle で、設定値変換しています。
2027         * bgColorClsClm が指定されている場合は、その値を利用したクラス属性を返します。
2028         * クラス名は、"row_" + 指定カラムの値 です。
2029         * 指定カラムの値 が、null または、空文字列の場合は、従来のゼブラ模様が優先されます。
2030         * また、行選択があれば、そちらが最優先されます。
2031         *
2032         * @og.rev 3.5.6.2 (2004/07/05) ViewForm_HTMLTable より移動
2033         * @og.rev 5.1.8.0 (2010/07/01) bgColorClsClmNo 対応
2034         *
2035         * @param       row 行番号( 0から始める )
2036         *
2037         * @return      行の色を指定する class 属性( cssファイルで指定 )
2038         * @see         #setBgColorClsClm( String )
2039         */
2040        protected String getBgColorCycleClass( final int row ) {
2041                String rtn = null ;
2042
2043                // 5.1.8.0 (2010/07/01) bgColorClsClmNo 対応
2044                if( bgColorClsClmNo >= 0 ) {
2045                        final String val = table.getValue( row,bgColorClsClmNo );
2046                        if( val != null && val.length() > 0 ) {
2047                                rtn = " class=\"row_" + val + "\"";
2048                        }
2049                }
2050
2051                if( rtn == null ) {
2052                        if( (row/bgColorCycle) % 2 == 0 ) {
2053                                rtn = colorRow0;                // 偶数の場合
2054                        }
2055                        else {
2056                                rtn = colorRow1;                // 奇数の場合
2057                        }
2058                }
2059
2060                return rtn ;
2061        }
2062
2063        /**
2064         * スクロールバー用のDIV要素を出力するかどうか(初期値はシステムパラメータ)
2065         *
2066         * スクロールバー対応する為、テーブルの先頭に、DIV要素を出力します。
2067         * 初期値は、システムパラメータ の VIEW_USE_SCROLLBAR です。
2068         * ※ 互換性の関係より、false になっています。
2069         * ※ 互換性の関係より、新しいタイプのヘッダー固定を、TYPE2 とします。
2070         *
2071         * @og.rev 3.5.6.4 (2004/07/16) 新規追加
2072         * @og.rev 3.8.0.3 (2005/07/15) barType 変数の追加
2073         * @og.rev 4.0.0.0 (2007/04/10) ヘッダー固定のスクロールタイプは、TYPE2 のみにする。
2074         *
2075         * @param  useBar  スクロールバー用のDIV要素の出力 [true:出力する/false:出力しない]
2076         */
2077        public void setUseScrollBar( final boolean useBar ) {
2078                useScrollBar  = useBar;
2079        }
2080
2081        /**
2082         * スクロールバー用の開始DIV要素返します。
2083         *
2084         * スクロールバー対応する為、テーブルの先頭に、DIV要素を出力します。
2085         * 初期値は、システムパラメータ の VIEW_USE_SCROLLBAR で指定されたDIV要素です。
2086         * DIV要素の開始タグになります。
2087         *
2088         * @og.rev 3.8.0.3 (2005/07/15) 新規追加
2089         * @og.rev 4.2.0.0 (2008/03/18) outerにwidthとheightを出すように修正
2090         *
2091         * @return  LAYER_ST スクロールバー用の開始DIV要素
2092         */
2093        protected String getScrollBarStartDiv() {
2094                final String layerStart ;
2095                if( useScrollBar ) {
2096                        // 6.1.0.0 (2014/12/26) refactoring:Prefer StringBuffer over += for concatenating strings
2097                        final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
2098                                .append( "<div id=\"divPos\" style=\"" );
2099                        if( height != null ){
2100                                buf.append( "height:" ).append( height ).append( ';' );
2101                        }
2102                        if( width != null ){
2103                                buf.append( "width:" ).append( width ).append( ';' );
2104                        }
2105                        buf.append( "\" ><div id=\"outer\"><div id=\"layer\" onscroll=\"SetScrollHeader(this);\"><div id=\"divHide\">" );
2106
2107                        layerStart = buf.toString();
2108                }
2109                else {
2110                        layerStart = LAYER_ST0;
2111                }
2112
2113                return layerStart;
2114        }
2115
2116        /**
2117         * スクロールバー用の終了DIV要素返します。
2118         *
2119         * スクロールバー対応する為、テーブルの終了に、DIV要素を出力します。
2120         * 初期値は、システムパラメータ の VIEW_USE_SCROLLBAR で指定されたDIV要素です。
2121         * DIV要素の終了タグになります。
2122         *
2123         * @og.rev 3.8.0.3 (2005/07/15) 新規追加
2124         *
2125         * @return  スクロールバー用の終了DIV要素
2126         */
2127        protected String getScrollBarEndDiv() {
2128                String layerEnd = LAYER_END0 ;
2129                if( useScrollBar ) {
2130                        layerEnd = LAYER_END2 ;
2131                }
2132                return layerEnd;
2133        }
2134
2135        /**
2136         * 指定の行番号まで画面をスクロールさせる場合の行番号を設定します。
2137         *
2138         * 画面をスクロール後、リンク等で他画面を表示後、戻ってきた場合に、
2139         * 先のスクロール位置まで戻します。
2140         * ただし、厳密に戻すことはできないため、大体のあたりに戻します。
2141         * 指定しない場合(クリアする場合)は、-1 をセットしてください。
2142         * useSelRowColor は、選択行に色づけするかどうかを指定します。
2143         *
2144         * @og.rev 3.7.0.3 (2005/03/01) 新規追加
2145         * @og.rev 3.7.1.1 (2005/05/31) 選択行マーカーの使用有無
2146         *
2147         * @param       rowNo   指定の行番号まで画面をスクロールさせる場合の行番号
2148         * @param       useSelRowColor  選択行マーカーの使用有無
2149         */
2150        public void setScrollRowNo( final int rowNo, final boolean useSelRowColor ) {
2151                scrollRowNo = rowNo;
2152                firstChecked = false;
2153                this.useSelRowColor = useSelRowColor;
2154        }
2155
2156        /**
2157         * 設定値に "_" が含まれている場合にレンデラーを使用するカラムをCSV形式で指定します。
2158         *
2159         * これは、従来の カラム定義の WRITABLE エディターと同等の働きを行うように
2160         * カラム属性を指定します。
2161         * WRITABLE エディターは、設定値にアンダーバー "_" が含まれている場合に、
2162         * その値を書込み禁止にする機能です。これは、エディター自身が値を判断して
2163         * 書き込み許可か禁止かを判断しています。
2164         * この動きを汎用的にするため、指定のカラムをCSV形式(CSV)で指定
2165         * することにより、レンデラーとエディターを設定値によって動的に切り替える
2166         * 機能を実現します。
2167         * その場合、表示/編集ともに、先頭のアンダーバーは削除されます。
2168         * また、全カラムについて、有効にする場合は、writableControl="*" を設定します。
2169         *
2170         * @og.rev 3.8.0.9 (2005/10/17) 新規追加
2171         * @og.rev 5.1.8.0 (2010/07/01) 内部ロジック変更(setBooleanArray)
2172         * @og.rev 7.0.1.5 (2018/12/10) writeCtrlで出力時のアンダーバー削除
2173         *
2174         * @param  wrtCtrl 書き込み制御を行いたいカラムをCSV形式で指定
2175         */
2176        public void setWritableControl( final String wrtCtrl ) {
2177                setBooleanArray( wrtCtrl,true,writeCtrl );
2178
2179                for( int i=0; i<writeCtrl.length; i++ ) {
2180                        if( writeCtrl[i] ) {
2181                                final DBColumnConfig config = dbColumn[i].getConfig();
2182                                config.setWriteControl( true );
2183                                dbColumn[i] = new DBColumn( config );
2184                                table.setDBColumn( i,dbColumn[i] );                             // DBTableModel にも書き戻す必要がある。
2185                        }
2186                }
2187        }
2188
2189        /**
2190         * CSV形式で指定されたカラムに、true/false の初期設定を行います。
2191         *
2192         * 従来は、各クラスで実装されていた処理を、一箇所にまとめます。
2193         * これにより、各種機能をあらかじめ実装しておきます。
2194         * 指定のカラムが、null の場合は、何も処理を行いません。(つまり、初期値のまま)
2195         * 指定のカラムが、* の場合は、すべてのカラムが指定されたとみなし、配列に値を設定します。
2196         * 指定のカラムが、""(ゼロ文字列)と、"-" の場合は、なにもカラムが指定されていないものとみなされ、
2197         * 初期値の逆で埋められます。
2198         *
2199         * @og.rev 5.1.8.0 (2010/07/01) 新規追加
2200         * @og.rev 6.2.1.0 (2015/03/13) カラム名のゼロ文字列と、"-" も除外する。
2201         * @og.rev 5.9.27.0 (2017/12/01) protectedにして子クラスでも使えるようにしておく
2202         *
2203         * @param  clsm    指定のカラムをCSV形式で指定
2204         * @param  def     設定する値
2205         * @param       arrays  設定するboolean配列
2206         */
2207        protected void setBooleanArray( final String clsm , final boolean def , final boolean[] arrays ) {
2208                if( clsm != null ) {
2209                        // 書き込み制御の許可 をカラム単位で設定。* の場合は、全カラム許可
2210                        if( "*".equals( clsm ) ) {
2211                                Arrays.fill( arrays,def );              // 全部埋める
2212                        }
2213                        // 6.2.1.0 (2015/03/13) カラム名のゼロ文字列と、"-" も除外する。
2214                        else if( "-".equals( clsm ) || clsm.isEmpty() ) {
2215                                Arrays.fill( arrays,!def );             // 全部逆で埋める
2216                        }
2217                        else {
2218                                Arrays.fill( arrays,!def );             // 一旦、全部逆で埋める
2219                                final String[] clmNames = StringUtil.csv2Array( clsm );
2220                                for( int i=0; i<clmNames.length; i++ ) {
2221                                        if( clmNames[i] != null && clmNames[i].length() > 0 ) {
2222                                                final int no = table.getColumnNo( clmNames[i] );
2223                                                if( no >= 0 ) { arrays[no] = def; }
2224                                        }
2225                                }
2226                        }
2227                }
2228        }
2229
2230        /**
2231         * ogPopup で検索結果の値を返すキーを、CSV形式で指定します。
2232         *
2233         * popup の検索結果を返す画面で、結果のラジオボタンにイベントセットします。
2234         * この場合、オープンもとのwindow に値を返しますが、そのキーをCSV形式で
2235         * 指定します。
2236         * なお、このメソッドは、一覧表示(HTMLTable)関係のビューのみでサポートして
2237         * いますが、チェックメソッドの関係で、それ以外のビューに適用しても素通り
2238         * するようにします。(エラーにしません)
2239         *
2240         * @og.rev 3.8.6.1 (2006/10/20) 新規追加
2241         *
2242         * @param  rtnKeys ogPopupで値を返すカラム文字列(CSV形式)
2243         */
2244        public void setPopupReturnKeys( final String rtnKeys ) {
2245                // このメソッドは、一覧表示(HTMLTable)関係のビューのみでサポートして
2246                // いますが、チェックメソッドの関係で、それ以外のビューに適用しても素通り
2247                // するようにします。(エラーにしません)
2248        }
2249
2250        /**
2251         * table要素に対して class 属性を設定します。
2252         *
2253         * 従来の システムリソースでのテーブルレイアウトの設定を廃止し、
2254         * CSSファイルで、指定するように変更しています。
2255         * これに伴い、CSSファイルのキーとして、クラス属性を出力します。
2256         * view(または、出力されるtableタグ)のレイアウトは、このクラス属性で
2257         * 指定することが可能になります。
2258         * 初期値は、viewTable です。
2259         *
2260         * @og.rev 4.0.0.0 (2007/04/16) 新規追加
2261         *
2262         * @param       cls     class属性を表す文字列
2263         */
2264        public void setTableClass( final String cls ) {
2265                if( cls != null ) {
2266                        clazz = cls;
2267                }
2268        }
2269
2270        /**
2271         * table要素に対して class 属性を返します。
2272         *
2273         * @og.rev 4.0.0.0 (2007/04/16) 新規追加
2274         * @og.rev 5.9.5.3 (2016/02/26) classにtableIdを付加して返す
2275         * @og.rev 6.4.6.1 (2016/06/03) tableId 廃止(利用目的を明確にするため、パラメータ名をviewClassに変更)
2276         *
2277         * @return      class属性を表す文字列
2278         */
2279        protected String getTableClass() {
2280                return clazz + " " + viewClass;                         // 6.4.6.1 (2016/06/03)
2281        }
2282
2283        /**
2284         * outerのIDを持つDIV要素にheightを指定します。
2285         *
2286         * ビューの高さ、幅を指定できるようにします。
2287         * 内部的には、useScrollBar="true" 時に、div id="divPos" に、
2288         * style 属性を設定しています。(実際は、もう少し複雑)
2289         * これによって1画面に2つのビューを出力する事も可能となります。
2290         * セットする場合は、単位(pt,% など)を付けてください。
2291         * 初期値はnullです。
2292         *
2293         * @og.rev 4.2.0.0 (2008/03/18) 新規追加
2294         *
2295         * @param       high    ビューの高さ
2296         */
2297        public void setHeight( final String high ) {
2298                height = high;
2299        }
2300
2301        /**
2302         * 設定されたheightを返します。
2303         *
2304         * テーブル以外に、高さ、幅を使用する場合に、値を取得できるようにしています。
2305         * これは、セットされた文字列そのものを返しますので、
2306         * 単位(pt,% など)が付いています。
2307         * 初期値はnullです。
2308         *
2309         * @og.rev 6.9.7.0 (2018/05/14) 新規追加
2310         *
2311         * @return      ビューの高さ(未設定の場合は、null)
2312         */
2313        protected String getHeight() {
2314                return height;
2315        }
2316
2317        /**
2318         * outerのIDを持つDIV要素にwidthを指定します。
2319         *
2320         * ビューの高さ、幅を指定できるようにします。
2321         * 内部的には、useScrollBar="true" 時に、div id="divPos" に、
2322         * style 属性を設定しています。(実際は、もう少し複雑)
2323         * これによって1画面に2つのビューを出力する事も可能となります。
2324         * セットする場合は、単位(pt,% など)を付けてください。
2325         * 初期値はnullです。
2326         *
2327         * @og.rev 4.2.0.0 (2008/03/18) 新規追加
2328         *
2329         * @param       wide    ビューの高さ
2330         */
2331        public void setWidth( final String wide ) {
2332                width = wide;
2333        }
2334
2335        /**
2336         * 設定されたwidthを返します。
2337         *
2338         * テーブル以外に、高さ、幅を使用する場合に、値を取得できるようにしています。
2339         * これは、セットされた文字列そのものを返しますので、
2340         * 単位(pt,% など)が付いています。
2341         *
2342         * @og.rev 6.9.7.0 (2018/05/14) 新規追加
2343         *
2344         * @return      ビューの高さ(未設定の場合は、null)
2345         */
2346        protected String getWidth() {
2347                return width;
2348        }
2349
2350        /**
2351         * リソースマネージャを設定します。
2352         * クロス集計時に、useColumnHeader="true"とした場合のみ設定されます。
2353         *
2354         * @og.rev 4.0.0.0 新規作成
2355         *
2356         * @param       res リソースマネージャー
2357         */
2358        public void setResourceManager( final ResourceManager res ) {
2359                resourceManager = res;
2360        }
2361
2362        /**
2363         * リソースマネージャを取得します。
2364         *
2365         * @og.rev 4.0.0.0 新規作成
2366         *
2367         * @return      ResourceManagerリソースマネージャー
2368         */
2369        protected ResourceManager getResourceManager() {
2370                return resourceManager;
2371        }
2372
2373        /**
2374         * 改廃Cのついていない行をスキップするかどうか指定します。
2375         *
2376         * "true" で、改廃Cのついた行をスキップします。
2377         * 初期値はfalseです。
2378         *
2379         * @og.rev 4.3.1.0 (2008/09/08) 新規追加
2380         *
2381         * @param       sne 改廃Cのついていない行をスキップするかどうか(true:スキップする/false:スキップしない)
2382         */
2383        public void setSkipNoEdit( final boolean sne ) {
2384                skipNoEdit = sne;
2385        }
2386
2387        /**
2388         * 改廃Cのついていない行をスキップするかどうか指定します。
2389         *
2390         * skipNoEdit="true"でかつ、編集されていない(改廃Cがついていない)場合のみ
2391         * trueを返します。
2392         *
2393         * @og.rev 4.3.1.0 (2008/09/08) 新規追加
2394         *
2395         * @param       row     行番号
2396         *
2397         * @return      スキップ対象行か
2398         */
2399        protected boolean isSkipNoEdit( final int row ) {
2400                return skipNoEdit && ( table.getModifyType( row ) == null || table.getModifyType( row ).isEmpty() );
2401        }
2402
2403        /**
2404         * 画面遷移なしモードに対応した形で処理を行うかを指定します。
2405         *
2406         * "true" で、画面遷移なしモードに対応します。
2407         * 初期値はfalseです。
2408         *
2409         * @og.rev 4.3.3.0 (2008/10/01) 新規追加
2410         *
2411         * @param       flag 画面遷移なしモードに対応するかどうか(true:対応する/false:対応しない)
2412         */
2413        public void setNoTransition( final boolean flag ) {
2414                noTransition = flag;
2415        }
2416
2417        /**
2418         * 画面遷移なしモードに対応した形で処理を行うかを返します。
2419         *
2420         * "true" で、画面遷移なしモードに対応します。
2421         * 初期値はfalseです。
2422         *
2423         * @og.rev 4.3.3.0 (2008/10/01) 新規追加
2424         *
2425         * @return      画面遷移なしモードに対応するかどうか(true:対応する/false:対応しない)
2426         */
2427        protected boolean isNoTransition() {
2428                return noTransition;
2429        }
2430
2431        /**
2432         * 該当行の行番号と改廃Cを出力します。
2433         * 出力形式は、 rid="[行番号]" kh="[改廃C]" です。
2434         * 改廃Cが付加されていない場合は、改廃Cがnullの場合は、kh属性は出力されません。
2435         * (画面遷移なしモードで使用します)
2436         *
2437         * @og.rev 4.3.3.0 (2008/10/01) 新規作成
2438         *
2439         * @param       row 行番号( 0から始める )
2440         *
2441         * @return      該当行の行番号と改廃C
2442         * @og.rtnNotNull
2443         */
2444        protected String getHiddenRowValue( final int row ) {
2445                String kh = "";
2446                if( table.getModifyType( row ) != null && table.getModifyType( row ).length() > 0 ) {
2447                        kh = " " + HIDDEN_CDKH_KEY + "=\"" + table.getModifyType( row ) + "\"";
2448                }
2449                return " " + HIDDEN_ROW_KEY + "=\"" + row + "\"" + kh;
2450        }
2451
2452        /**
2453         * ビューで表示したカラムの一覧をCSV形式で返します。
2454         *
2455         * @og.rev 5.1.6.0 (2010/05/01) 新規追加
2456         *
2457         * @return      ビューで表示したカラムの一覧
2458         * @og.rtnNotNull
2459         */
2460        public String getViewClms() {
2461                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
2462                for( int i=0; i<clmDisplay.length; i++ ) {
2463                        if( clmDisplay[i] && !( rowWritableFlag && i==0 ) ) {
2464                                if( buf.length() > 0 ) { buf.append( ',' ); }
2465                                buf.append( dbColumn[i].getName() );
2466                        }
2467                }
2468                return buf.toString();
2469        }
2470
2471        /**
2472         * ビューで表示したカラムの一覧をCSV形式で返します。
2473         *
2474         * このメソッドでは、TableFormatter を使用して表示されたカラム一覧を求めます。
2475         *
2476         * @og.rev 6.4.3.4 (2016/03/11) TableFormatter を使用して表示されたカラム一覧を求めます。
2477         *
2478         * @param       format TableFormatterオブジェクト
2479         * @return      ビューで表示したカラムの一覧
2480         * @og.rtnNotNull
2481         */
2482        protected String getViewClms( final TableFormatter format ) {
2483                return format.getLocationStream()                                                                               // IntStream の取得
2484                                                .filter(   loc -> loc >= 0 )                                                    // 処理条件
2485                                                .mapToObj( loc -> table.getColumnName( loc ) )                  // int から String へStreamの変換
2486                                                .collect( Collectors.joining( "," ) );                                  // CSV連結
2487        }
2488
2489        /**
2490         * 表示項目の編集(並び替え)が可能かどうかを返します。
2491         *
2492         * @og.rev 5.1.6.0 (2010/05/01) 新規追加
2493         *
2494         * @return      表示項目の編集(並び替え)が可能かどうか(true:可能)
2495         */
2496        public boolean isEditable() {
2497                return true;
2498        }
2499
2500        /**
2501         * このViewFormが作成された画面IDをセットします。
2502         *
2503         * @og.rev 5.1.7.0 (2010/06/01) 新規追加
2504         *
2505         * @param gamenId 画面ID
2506         */
2507        public void setGamenId( final String gamenId ) {
2508                this.gamenId = gamenId;
2509        }
2510
2511        /**
2512         * このViewFormが作成された画面IDを返します。
2513         *
2514         * @og.rev 5.1.7.0 (2010/06/01) 新規追加
2515         *
2516         * @return      画面ID
2517         */
2518        public String getGamenId() {
2519                return gamenId;
2520        }
2521
2522        /**
2523         * カラムが一括入力アシスト機能を利用するかどうかを返します。
2524         *
2525         * 条件は、一括入力アシストカラムで、かつ、書き込み許可(isColumnWritable(clm)==true)の場合とする。
2526         *
2527         * @og.rev 5.2.1.0 (2010/10/01) 新規作成
2528         *
2529         * @param       column カラム番号
2530         *
2531         * @return      利用する(true)/しない(false)
2532         */
2533        protected boolean isClmBulkSet( final int column ) {
2534                return clmBulkSet[column] && clmWritable[column];
2535        }
2536
2537        /**
2538         * 一括入力カラムのアシスト機能を利用するカラム名を、CSV形式で与えます。
2539         *
2540         * これは、カラムの書き込み時に、一括入力可能なカラムをヘッダーに表示し、
2541         * 一括登録できる機能を提供します。
2542         * この機能は、jsp/common/bulkSet.js JavaScript とともに提供されます。
2543         * IE については、クリップボードも利用できます。Ctrl-C と Ctrl-V でそれぞれ
2544         * 一連のカラムの値の取り出しと書き込みが可能になります。
2545         * "*" を指定すると、すべてのカラムを(columnBulkSet)指定したことになります。
2546         *
2547         * @og.rev 5.2.1.0 (2010/10/01) 新規作成
2548         * @og.rev 6.2.0.0 (2015/02/27) Popup(isRenderer=false のviewMarker)のBuikSet Off化対応
2549         *
2550         * @param       columnName      例:"OYA,KO,HJO,SU,DYSET,DYUPD"
2551         */
2552        public void setColumnBulkSet( final String columnName ) {
2553                setBooleanArray( columnName,true,clmBulkSet );
2554
2555                // 6.2.0.0 (2015/02/27) Popup(isRenderer=false のviewMarker)のBuikSet Off化対応
2556                // result.jsp から update.jsp に画面遷移するときに、再セットされるので、
2557                // 旧のView属性のコピーが必要。(コピーのタイミングでは、早すぎて、ここで書き換えられてしまう。)
2558                if( editMarker != null ) {
2559                        final int[] clmNos = editMarker.getColumnNos();
2560                        if( clmNos != null ) {
2561                                for( int i=0; i<clmNos.length; i++ ) {
2562                                        clmBulkSet[clmNos[i]] = false ; // 6.2.0.0 (2015/02/27) BulkSetしない
2563                                }
2564                        }
2565                }
2566        }
2567
2568        /**
2569         * 引数のフォーマッターに、noDisplayカラムのロケーションをクリアします。
2570         *
2571         * フォーマッター系の noDisplay 処理になります。
2572         *
2573         * @og.rev 6.2.0.0 (2015/02/27) フォーマット系の noDisplay 対応
2574         * @og.rev 6.2.0.1 (2015/03/06) 非表示のマーカーに、Formatter#NO_DISPLAY を使用する。
2575         *
2576         * @param       format  フォーマッター
2577         */
2578        protected void setFormatNoDisplay( final TableFormatter format ) {
2579                final int size = format.getLocationSize();
2580                for( int cl=0; cl<size; cl++ ) {
2581                        final int loc = format.getLocation( cl );
2582                        if( loc >= 0 && !isColumnDisplay( loc ) ) {     // 6.2.0.1 (2015/03/06) 非表示のマーカー
2583                                format.setNoDisplay( cl );                              // 6.2.0.1 (2015/03/06) 非表示のマーカー
2584                        }
2585                }
2586        }
2587
2588        /**
2589         * このViewFormを作成するにあたり、区別するためのクラス属性をセットします。
2590         *
2591         * 通常は、viewForm より tableId を設定します。
2592         * SplitViewTag を使用する場合は、左右分割のため、同じtableId になるため、
2593         * 左右で異なるclassを設定してください。
2594         *
2595         * @og.rev 6.4.6.1 (2016/06/03) 新規追加
2596         *
2597         * @param clazz Viewのクラス属性
2598         */
2599        public void setViewClass( final String clazz ) {
2600                if( clazz != null ) {
2601                        this.viewClass = clazz;
2602                }
2603        }
2604
2605        /**
2606         * このViewFormを作成するにあたり、区別するためのクラス属性を取得します。
2607         *
2608         * 通常は、viewForm より tableId を設定します。
2609         * SplitViewTag を使用する場合は、左右分割のため、同じtableId になるため、
2610         * 左右で異なるclassを設定してください。
2611         *
2612         * @og.rev 6.4.6.1 (2016/06/03) 新規追加
2613         *
2614         * @return Viewのクラス属性
2615         */
2616        protected String getViewClass() {
2617                return viewClass;
2618        }
2619}