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.plugin.view; 017 018import org.opengion.hayabusa.common.HybsSystem; 019import org.opengion.hayabusa.common.HybsSystemException; 020import org.opengion.hayabusa.db.DBTableModel; 021import org.opengion.fukurou.util.StringUtil; 022import org.opengion.hayabusa.html.TableFormatter; 023 024import java.util.List; 025 026/** 027 * ヘッダ、フッタ、ボディを指定して作成する、自由レイアウトが可能な、カスタムテーブル表示クラスです。 028 * このクラスは、ViewForm_HTMLFormatTable クラスの代替えとしても使用できます。 029 * その場合は、thead のみ指定すれば、同じフォームが tbody にも適用されます。 030 * これは、まさに、ViewForm_HTMLFormatTable と同じです。 031 * 032 * AbstractViewForm により、setter/getterメソッドのデフォルト実装を提供しています。 033 * 各HTMLのタグに必要な setter/getterメソッドのみ,追加定義しています。 034 * 035 * AbstractViewForm を継承している為,ロケールに応じたラベルを出力させる事が出来ます。 036 * 037 * @og.group 画面表示 038 * 039 * @version 4.0 040 * @author Kazuhiko Hasegawa 041 * @since JDK5.0, 042 */ 043public class ViewForm_HTMLCustomTable extends ViewForm_HTMLTable { 044 //* このプログラムのVERSION文字列を設定します。 {@value} */ 045 private static final String VERSION = "5.7.6.2 (2014/05/16)" ; 046 047 // 3.5.4.0 (2003/11/25) TableFormatter クラス追加 048 // 4.3.1.0 (2008/09/08) protectedに変更 049 /** ヘッダーフォーマット変数 */ 050 protected TableFormatter headerFormat = null; 051 /** ボディーフォーマット配列変数 */ 052 protected TableFormatter[] bodyFormats = null; 053 /** フッターフォーマット変数 */ 054 protected TableFormatter footerFormat = null; 055 /** ボディーフォーマット数 */ 056 protected int bodyFormatsCount = 0; 057 058 // 3.5.4.6 (2004/01/30) 初期値変更 059 /** ボディーフォーマット最大数 初期値:{@value} */ 060// protected static final int BODYFORMAT_MAX_COUNT = 10; 061 protected static final int BODYFORMAT_MAX_COUNT = 15; // 5.7.6.2 (2014/05/16) 062 063 /** 064 * DBTableModel から HTML文字列を作成して返します。 065 * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。 066 * 表示残りデータが pageSize 以下の場合は,残りのデータをすべて出力します。 067 * 068 * @og.rev 3.5.0.0 (2003/09/17) BODY要素の noClass 属性を追加。 069 * @og.rev 3.5.0.0 (2003/09/17) <tr>属性は、元のフォーマットのまま使用します。 070 * @og.rev 3.5.2.0 (2003/10/20) ヘッダー繰り返し属性( headerSkipCount )を採用 071 * @og.rev 3.5.3.1 (2003/10/31) skip属性を採用。headerLine のキャッシュクリア 072 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更。 073 * @og.rev 3.5.5.0 (2004/03/12) systemFormat(例:[KEY.カラム名]形式等)の対応 074 * @og.rev 3.5.5.0 (2004/03/12) No 欄そのものの作成判断ロジックを追加 075 * @og.rev 3.5.5.7 (2004/05/10) [#カラム名] , [$カラム名] に対応 076 * @og.rev 3.5.6.0 (2004/06/18) '!' 値のみ 追加 既存の '$' は、レンデラー 077 * @og.rev 3.5.6.2 (2004/07/05) makeFormat 処理をgetTableHead メソッドから移動 078 * @og.rev 3.5.6.4 (2004/07/16) ヘッダーとボディー部をJavaScriptで分離 079 * @og.rev 4.0.0.0 (2005/01/31) 新規作成(getColumnClassName ⇒ getColumnDbType) 080 * @og.rev 3.7.0.3 (2005/03/01) getBgColorCycleClass に、選択行マーカーを採用 081 * @og.rev 4.3.1.0 (2008/09/08) フォーマットが設定されていない場合のエラー追加・編集行のみを表示する属性(isSkipNoEdit)追加 082 * @og.rev 4.3.3.0 (2008/10/01) noTransition属性対応 083 * @og.rev 4.3.7.4 (2009/07/01) tbodyタグの入れ子を解消(FireFox対応) 084 * 085 * @param startNo 表示開始位置 086 * @param pageSize 表示件数 087 * 088 * @return DBTableModelから作成された HTML文字列 089 */ 090 @Override 091 public String create( final int startNo, final int pageSize ) { 092 if( getRowCount() == 0 ) { return ""; } // 暫定処置 093 094 // 4.3.1.0 (2008/09/08) 095 if( headerFormat == null ) { 096 String errMsg = "ViewTagで canUseFormat() = true の場合、Formatter は必須です。"; 097 throw new HybsSystemException( errMsg ); 098 } 099 100 headerLine = null; // 3.5.3.1 (2003/10/31) キャッシュクリア 101 102 int lastNo = getLastNo( startNo, pageSize ); 103 int blc = getBackLinkCount(); 104 int hsc = getHeaderSkipCount(); // 3.5.2.0 (2003/10/20) 105 int hscCnt = 1; // 3.5.2.0 (2003/10/20) 106 107 StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE ); 108 109 headerFormat.makeFormat( getDBTableModel() ); // 3.5.6.2 (2004/07/05) 移動 110 111 out.append( getCountForm( startNo,pageSize ) ); 112 out.append( getHeader() ); 113 114 if( bodyFormatsCount == 0 ) { 115 bodyFormats[0] = headerFormat ; 116 bodyFormatsCount ++ ; 117 } 118 else { 119 for( int i=0; i<bodyFormatsCount; i++ ) { 120 bodyFormats[i].makeFormat( getDBTableModel() ); 121 } 122 } 123 124 int bgClrCnt = 0; 125 for( int row=startNo; row<lastNo; row++ ) { 126 if( isSkip( row ) || isSkipNoEdit( row ) ) { continue; } // 4.3.1.0 (2008/09/08) 127 for( int i=0; i<bodyFormatsCount; i++ ) { 128 TableFormatter bodyFormat = bodyFormats[i]; 129 if( ! bodyFormat.isUse( row,getDBTableModel() ) ) { continue; } // 3.5.4.0 (2003/11/25) 130 out.append("<tbody").append( getBgColorCycleClass( bgClrCnt++,row ) ); 131 if( isNoTransition() ) { // 4.3.3.0 (2008/10/01) 132 out.append( getHiddenRowValue( row ) ); 133 } 134 out.append(">"); // 3.7.0.3 (2005/03/01) 135 out.append( bodyFormat.getTrTag() ); 136 137 // 3.5.5.0 (2004/03/12) No 欄そのものの作成判断追加 138 if( isNumberDisplay() ) { 139 String ckboxTD = "<td" + bodyFormat.getRowspan() + ">"; 140 out.append( makeCheckbox( ckboxTD,row,blc ) ); 141 } 142 143 int cl = 0; 144 for( ; cl < bodyFormat.getLocationSize(); cl++ ) { 145 String fmt = bodyFormat.getFormat(cl); 146 int loc = bodyFormat.getLocation(cl); // 3.5.5.0 147 if( ! bodyFormat.isNoClass() && loc >= 0 ) { // 3.5.5.7 (2004/05/10) 148 StringBuilder newtg = new StringBuilder( HybsSystem.BUFFER_LARGE ); 149 newtg.append("<td class=\""); 150 newtg.append( getColumnDbType(loc) ); // 4.0.0 (2005/01/31) 151 newtg.append("\" "); 152 String tdclass = newtg.toString(); 153 fmt = StringUtil.replace( bodyFormat.getFormat(cl) ,"<td", tdclass ); 154 } 155 out.append( fmt ); // 3.5.0.0 156 // 3.5.5.7 (2004/05/10) #,$ 対応 157 if( loc >= 0 ) { 158 switch( bodyFormat.getType(cl) ) { 159 case '#' : out.append( getColumnLabel(loc) ); break; 160 case '$' : out.append( getRendererValue(row,loc) ); break; 161 case '!' : out.append( getValue(row,loc) ); break; 162 default : out.append( getValueLabel(row,loc) ); break; 163 } 164 } 165 else { 166 out.append( bodyFormat.getSystemFormat(row,loc) ); 167 } 168 } 169 out.append( bodyFormat.getFormat(cl) ); 170 out.append("</tbody>").append( HybsSystem.CR ); 171 } 172 173 // 3.5.2.0 (2003/10/20) ヘッダー繰り返し属性( headerSkipCount )を採用 174 if( hsc > 0 && hscCnt % hsc == 0 ) { 175 out.append("<tbody class=\"row_h\"").append(" >"); 176 out.append( getHeadLine() ); 177 out.append("</tbody>"); 178 hscCnt = 1; 179 } 180 else { 181 hscCnt ++ ; 182 } 183 } 184 185 if( footerFormat != null ) { 186 out.append( getTableFoot() ); 187 } 188 189 out.append("</table>").append( HybsSystem.CR ); 190 191 out.append( getScrollBarEndDiv() ); // 3.8.0.3 (2005/07/15) 192 return out.toString(); 193 } 194 195 /** 196 * 内容をクリア(初期化)します。 197 * 198 * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。 199 * @og.rev 3.5.0.0 (2003/09/17) Noカラムに、表示を全て消せるように、class 属性を追加。 200 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更。 201 * 202 */ 203 @Override 204 public void clear() { 205 super.clear(); 206 headerFormat = null; 207 bodyFormats = null; 208 footerFormat = null; 209 bodyFormatsCount = 0; 210 } 211 212 /** 213 * DBTableModel から テーブルのタグ文字列を作成して返します。 214 * 215 * @og.rev 3.5.0.0 (2003/09/17) <tr>属性は、元のフォーマットのまま使用します。 216 * @og.rev 3.5.1.0 (2003/10/03) Noカラムに、numberType 属性を追加 217 * @og.rev 3.5.2.0 (2003/10/20) ヘッダー繰り返し部をgetHeadLine()へ移動 218 * @og.rev 3.5.3.1 (2003/10/31) VERCHAR2 を VARCHAR2 に修正。 219 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更。 220 * @og.rev 3.5.5.0 (2004/03/12) No 欄そのものの作成判断ロジックを追加 221 * @og.rev 3.5.6.2 (2004/07/05) makeFormat 処理をcreate メソッドの頭に移動 222 * @og.rev 3.5.6.5 (2004/08/09) thead に、id="header" を追加 223 * @og.rev 4.0.0.0 (2005/01/31) DBColumn の 属性(CLS_NM)から、DBTYPEに変更 224 * 225 * @return テーブルのタグ文字列 226 */ 227 @Override 228 protected String getTableHead() { 229 230 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 231 // 3.5.5.0 (2004/03/12) No 欄そのものの作成判断追加 232 if( isNumberDisplay() ) { 233 buf.append("<colgroup class=\"X\" />"); // 4.0.0 (2005/01/31) 234 buf.append("<colgroup class=\"BIT\" />"); 235 buf.append("<colgroup class=\"S9\" />"); // 4.0.0 (2005/01/31) 236 buf.append(HybsSystem.CR); 237 } 238 239 // 3.5.2.0 (2003/10/20) ヘッダー繰り返し部をgetHeadLine()へ移動 240 buf.append("<thead id=\"header\">").append( HybsSystem.CR ); // 3.5.6.5 (2004/08/09) 241 buf.append( getHeadLine() ); 242 buf.append("</thead>").append( HybsSystem.CR ); 243 244 return buf.toString(); 245 } 246 247 /** 248 * ヘッダー繰り返し部を、getTableHead()メソッドから分離。 249 * 250 * @og.rev 3.5.6.2 (2004/07/05) HTMLCustomTableScrollBar 用に新規作成 251 * 252 * @return テーブルのタグ文字列 253 */ 254 @Override 255 protected String getHeadLine() { 256 return getHeadLine( "<th" ) ; 257 } 258 259 /** 260 * ヘッダー繰り返し部を、getTableHead()メソッドから分離。 261 * 262 * @og.rev 3.5.2.0 (2003/10/20) 新規作成 263 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更。 264 * @og.rev 3.5.4.3 (2004/01/05) useCheckControl 属性の機能を追加 265 * @og.rev 3.5.4.6 (2004/01/30) numberType="none" 時の処理を追加(Noラベルを出さない) 266 * @og.rev 3.5.4.7 (2004/02/06) ヘッダーにソート機能用のリンクを追加します。 267 * @og.rev 3.5.5.0 (2004/03/12) systemFormat(例:[KEY.カラム名]形式等)の対応 268 * @og.rev 3.5.5.0 (2004/03/12) No 欄そのものの作成判断ロジックを追加 269 * @og.rev 3.5.6.2 (2004/07/05) HTMLCustomTableScrollBar 用に引数追加 270 * @og.rev 3.7.0.1 (2005/01/31) 全件チェックコントロール処理変更 271 * 272 * @param thTag タグの文字列 273 * 274 * @return テーブルのタグ文字列 275 */ 276 @Override 277 protected String getHeadLine( final String thTag ) { 278 if( headerLine != null ) { return headerLine; } // キャッシュを返す。 279 280 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 281 282 buf.append( headerFormat.getTrTag() ).append( HybsSystem.CR ); 283 284 // 3.5.5.0 (2004/03/12) No 欄そのものの作成判断追加 285 if( isNumberDisplay() ) { 286 // 3.5.4.3 (2004/01/05) 追加分 287 if( isUseCheckControl() && "checkbox".equals( getSelectedType() ) ) { 288 buf.append( thTag ).append( headerFormat.getRowspan() ).append("></th>"); 289 buf.append( thTag ).append( headerFormat.getRowspan() ); 290 buf.append(">").append( getAllCheckControl() ).append( "</th>"); 291 buf.append( thTag ).append( headerFormat.getRowspan() ); 292 buf.append(">").append( getNumberHeader() ).append("</th>"); // 3.5.4.6 (2004/01/30) 293 } 294 else { 295 buf.append( thTag ).append(" colspan=\"3\""); 296 buf.append( headerFormat.getRowspan() ); 297 buf.append(">").append( getNumberHeader() ).append("</th>"); // 3.5.4.6 (2004/01/30) 298 } 299 } 300 301 int cl = 0; 302 for( ; cl < headerFormat.getLocationSize(); cl++ ) { 303 buf.append( StringUtil.replace( headerFormat.getFormat(cl) ,"td","th" )); 304 int loc = headerFormat.getLocation(cl); 305 if( loc >= 0 ) { buf.append( getSortedColumnLabel(loc) ); } 306 } 307 buf.append( StringUtil.replace( headerFormat.getFormat(cl) ,"td","th" ) ).append( HybsSystem.CR ); 308 309 headerLine = buf.toString(); 310 return headerLine; 311 } 312 313 /** 314 * DBTableModel から テーブルのタグ文字列を作成して返します。 315 * 316 * @og.rev 3.5.0.0 (2003/09/17) <tr>属性は、元のフォーマットのまま使用します。 317 * @og.rev 3.5.1.0 (2003/10/03) Noカラムに、numberType 属性を追加 318 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更。 319 * @og.rev 3.5.4.7 (2004/02/06) ヘッダーにソート機能用のリンクを追加します。 320 * @og.rev 3.5.5.0 (2004/03/12) systemFormat(例:[KEY.カラム名]形式等)の対応 321 * @og.rev 3.5.5.0 (2004/03/12) No 欄そのものの作成判断ロジックを追加 322 * 323 * @return テーブルのタグ文字列 324 */ 325 protected String getTableFoot() { 326 footerFormat.makeFormat( getDBTableModel() ); 327 328 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 329 330 buf.append("<tfoot>").append( HybsSystem.CR ); 331 buf.append( footerFormat.getTrTag() ).append( HybsSystem.CR ); 332 333 // 3.5.5.0 (2004/03/12) No 欄そのものの作成判断追加 334 if( isNumberDisplay() ) { 335 buf.append(" <th"); 336 buf.append(" colspan=\"3\""); 337 buf.append( footerFormat.getRowspan() ); 338 buf.append("></th>"); 339 } 340 341 int cl = 0; 342 for( ; cl < footerFormat.getLocationSize(); cl++ ) { 343 int loc = footerFormat.getLocation(cl); 344 if( loc >= 0 ) { buf.append( getSortedColumnLabel(loc) ); } 345 } 346 buf.append( footerFormat.getFormat(cl) ).append( HybsSystem.CR ); 347 buf.append("</tfoot>").append( HybsSystem.CR ); 348 349 return buf.toString(); 350 } 351 352 /** 353 * フォーマットを設定します。 354 * 355 * @og.rev 3.5.4.0 (2003/11/25) 新規作成 356 * @og.rev 3.5.4.4 (2004/01/16) 配列の最大数を変更 357 * @og.rev 3.5.5.5 (2004/04/23) headerFormat が定義されていない場合はエラー 358 * 359 * @param list TableFormatterのリスト 360 */ 361 @Override 362 public void setFormatterList( final List<TableFormatter> list ) { // 4.3.3.6 (2008/11/15) Generics警告対応 363 bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT]; 364 365 bodyFormatsCount = 0; 366 for( int i=0; i<list.size(); i++ ) { 367 TableFormatter format = list.get( i ); // 4.3.3.6 (2008/11/15) Generics警告対応 368 369 switch( format.getFormatType() ) { 370 case TYPE_HEAD : headerFormat = format; break; 371 case TYPE_BODY : bodyFormats[bodyFormatsCount++] = format; break; 372 case TYPE_FOOT : footerFormat = format; break; 373 default : String errMsg = "FormatterType の定義外の値が指定されました。"; 374 // 4.3.4.4 (2009/01/01) 375 throw new HybsSystemException( errMsg ); 376 } 377 } 378 379 // 3.5.5.5 (2004/04/23) headerFormat が定義されていない場合はエラー 380 if( headerFormat == null ) { 381 String errMsg = "h:thead タグの、フォーマットの指定は必須です。"; 382 throw new HybsSystemException( errMsg ); 383 } 384 } 385 386 /** 387 * フォーマットメソッドを使用できるかどうかを問い合わせます。 388 * 389 * @return 使用可能(true)/ 使用不可能 (false) 390 */ 391 @Override 392 public boolean canUseFormat() { 393 return true; 394 } 395 396 /** 397 * ビューで表示したカラムの一覧をカンマ区切りで返します。 398 * 399 * @og.rev 5.1.6.0 (2010/05/01) 新規追加 400 * 401 * @return ビューで表示したカラムの一覧 402 */ 403 @Override 404 public String getViewClms() { 405 DBTableModel table = getDBTableModel(); 406 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 407 for( int i=0; i<headerFormat.getLocationSize(); i++ ) { 408 if( buf.length() > 0 ) { buf.append( ',' ); } 409 buf.append( table.getColumnName( headerFormat.getLocation( i ) ) ); 410 } 411 return buf.toString(); 412 } 413}