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