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.report; 017 018import static org.opengion.fukurou.system.HybsConst.CR ; // 6.1.0.0 (2014/12/26) 019import org.opengion.fukurou.system.LogWriter; 020import org.opengion.fukurou.util.StringUtil; 021import org.opengion.fukurou.util.FileUtil; 022import org.opengion.fukurou.system.Closer ; 023import org.opengion.hayabusa.common.HybsSystem; 024import org.opengion.hayabusa.common.HybsSystemException; 025import org.opengion.hayabusa.db.DBTableModel; 026import org.opengion.hayabusa.db.DBColumn; 027import org.opengion.hayabusa.resource.ResourceManager; 028 029import java.io.File; 030import java.io.BufferedReader; 031import java.io.PrintWriter; 032 033/** 034 * DBTableReport インターフェース のデフォルト実装クラスです。 035 * writeReport() を、オーバーライドすれば,各種出力フォーマットに合わせた 036 * サブクラスを実現する事が可能です。 037 * 038 * @og.group 帳票システム 039 * 040 * @version 4.0 041 * @author Kazuhiko Hasegawa 042 * @since JDK5.0, 043 */ 044public abstract class AbstractDBTableReport implements DBTableReport { 045 private static final String ENCODE = HybsSystem.REPORT_ENCODE ; 046 private static final String PAGEBREAK = "PAGEBREAK"; 047 048 protected String[] headerKeys ; // 固定部の key 部分を指定する。カンマで複数指定できる。 049 protected String[] headerVals ; // 固定部の key に対応する値を指定する。 050 protected String[] footerKeys ; // 繰り返し部の終了後に表示する key 部分を指定する。カンマで複数指定できる。 051 protected String[] footerVals ; // 繰り返し部の終了後に表示する key に対する値を指定する。 052 protected boolean pageEndCut ; // ボディー部(繰り返し部)がなくなったときに、それ以降のページを出力するか指定する。 053 protected int maxRowCount ; // 自動計算方式を採用 054 protected int pageRowCount; // 過去のページの最大件数。 3.7.0.1 (2005/01/31) 055 protected int lineCopyCnt ; // LINE_COPY した際の加算行番号。 4.0.0 (2007/06/08) 056 protected ResourceManager resource ; // 4.0.0 (2005/01/31) 057 protected PrintWriter writer ; 058 protected BufferedReader reader ; 059 protected File templateFile ; // 3.8.0.0 (2005/06/07) 060 protected File firstTemplateFile; // 3.8.0.0 (2005/06/07) 061 protected String htmlDir ; 062 protected String htmlFileKey ; 063 protected String ykno ; // 3.8.5.1 (2006/04/28) 追加 064 protected DBTableModel table ; 065 066 protected int pageCount ; 067 protected int maxPageCount = 1000; 068 protected boolean rowOver ; // データ件数分のカラムを要求されると、true にセットされる。 069 protected boolean dataOver ; // 3.8.1.2 (2005/12/19) データがなくなると、true にセットされる。 070 protected String listId ; // 3.6.1.0 (2005/01/05) 帳票ID追加 071 072 // 3.6.0.0 (2004/09/24) フォーマットエラーの判定(formatErr)を、子クラスから移動します。 073 private boolean formatErr ; // フォーマットエラーの判定 074 075 // 3.7.0.1 (2005/01/31) ページブレイク時の処理 076 private int pbClmNo = -1; // PAGEBREAK カラムの番号 077 private boolean pageBreak ; // PAGEBREAK = "1" が見つかった時、true 078 private int tableSize ; 079 080 /** 081 * デフォルトコンストラクター 082 * 083 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 084 */ 085 protected AbstractDBTableReport() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 086 087 /** 088 * DBTableModel から データを作成して,PrintWriter に書き出します。 089 * 090 */ 091 public void writeReport() { 092 setHeaderFooter(); 093 initReader(); 094 initWriter(); 095 String str ; 096 while( (str = readLine()) != null ) { 097 println( changeData( str ) ); 098 } 099 close(); 100 } 101 102 /** 103 * 入力文字列 を読み取って、出力します。 104 * tr タグを目印に、1行(trタグ間)ずつ取り出します。 105 * 読み取りを終了する場合は、null を返します。 106 * 各サブクラスで実装してください。 107 * 108 * @return 出力文字列 109 */ 110 protected abstract String readLine() ; 111 112 /** 113 * 入力文字列 を加工して、出力します。 114 * {@XXXX} をテーブルモデルより読み取り、値をセットします。 115 * 各サブクラスで実装してください。 116 * 117 * @param inLine 入力文字列 118 * 119 * @return 出力文字列 120 */ 121 protected abstract String changeData( final String inLine ) ; 122 123 /** 124 * 入力文字列 を読み取って、出力します。 125 * 各サブクラスで実装してください。 126 * 127 * @param line 出力文字列 128 */ 129 protected abstract void println( final String line ) ; 130 131 /** 132 * リソースマネージャーをセットします。 133 * これは、言語(ロケール)に応じた DBColumn をあらかじめ設定しておく為に 134 * 必要です。 135 * リソースマネージャーが設定されていない、または、所定のキーの DBColumn が 136 * リソースに存在しない場合は、内部で DBColumn オブジェクトを作成します。 137 * 138 * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更 139 * 140 * @param resource リソースマネージャー 141 */ 142 public void setResourceManager( final ResourceManager resource ) { 143 this.resource = resource; 144 } 145 146 /** 147 * 帳票ID をセットします。 148 * この帳票IDを利用して、画像ファイル等のセーブディレクトリを求めます。 149 * 150 * @og.rev 3.6.1.0 (2005/01/05) 新規作成 151 * 152 * @param listId 帳票ID 153 */ 154 public void setListId( final String listId ) { 155 this.listId = listId ; 156 } 157 158 /** 159 * DBTableModel をセットします。 160 * 161 * @og.rev 3.7.0.1 (2005/01/31) ページブレイク時の処理 162 * 163 * @param table DBTableModelオブジェクト 164 */ 165 public void setDBTableModel( final DBTableModel table ) { 166 this.table = table; 167 // 3.7.0.1 (2005/01/31) ページブレイク時の処理 168 tableSize = table.getRowCount(); 169 pbClmNo = table.getColumnNo( PAGEBREAK,false ); // 存在しない場合は、-1 170 } 171 172 /** 173 * 雛型ファイル名をセットします。 174 * 175 * @og.rev 3.6.0.0 (2004/09/17) メソッド名の変更。setInputFile ⇒ setTemplateFile 176 * @og.rev 3.8.0.0 (2005/06/07) 引数を String ⇒ File に変更 177 * 178 * @param inFile 雛型ファイル名 179 */ 180 public void setTemplateFile( final File inFile ) { 181 templateFile = inFile; 182 } 183 184 /** 185 * 最初のページのみに使用する雛型ファイル名をセットします。 186 * 187 * @og.rev 3.6.0.0 (2004/09/17) 新規追加 188 * @og.rev 3.8.0.0 (2005/06/07) 引数を String ⇒ File に変更 189 * 190 * @param inFile 最初のページの雛型ファイル名 191 */ 192 public void setFirstTemplateFile( final File inFile ) { 193 firstTemplateFile = inFile; 194 } 195 196 /** 197 * 変換後ファイルを出力するディレクトリ名をセットします。 198 * ディレクトリが存在しない場合は、新規に作成します。 199 * 200 * @og.rev 3.7.1.1 (2005/05/23) フォルダがない場合は、複数階層分のフォルダを自動で作成します。 201 * 202 * @param outDir 出力ディレクトリ 203 */ 204 public void setOutputDir( final String outDir ) { 205 htmlDir = outDir; 206 207 final File dir = new File(htmlDir); 208 if( ! dir.exists() && ! dir.mkdirs() ) { 209 final String errMsg = "ディレクトリの作成に失敗しました。[" + htmlDir + "]"; 210 throw new HybsSystemException( errMsg ); 211 } 212 } 213 214 /** 215 * 変換後ファイルキーをセットします。 216 * キーとは、拡張子の無い状態までのファイル名です。 217 * 変換後ファイルは、複数発生します。 218 * 実際に出力されるファイル名は、outFile + "_連番.html" となります。 219 * 220 * @param outFile 出力ファイル名の共通部 221 */ 222 public void setOutputFileKey( final String outFile ) { 223 htmlFileKey = outFile; 224 } 225 226 /** 227 * 帳票起動された要求番号をセットします。 228 * 229 * @og.rev 3.8.5.1 (2006/04/28) 新規追加 230 * 231 * @param ykno 要求番号 232 */ 233 public void setYkno( final String ykno ) { 234 this.ykno = ykno; 235 } 236 237 /** 238 * 固定部の key 部分を指定します。 239 * カンマで複数指定できます。 240 * 241 * @og.rev 3.5.6.0 (2004/06/18) 配列の設定は、arraycopy して取り込みます。 242 * 243 * @param hKeys 固定部のキー配列(可変長引数) 244 */ 245 public void setHeaderKeys( final String... hKeys ) { 246 if( hKeys != null && hKeys.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 247 final int size = hKeys.length ; 248 headerKeys = new String[size]; 249 System.arraycopy( hKeys,0,headerKeys,0,size ); 250 } 251 else { 252 headerKeys = null; 253 } 254 } 255 256 /** 257 * 固定部のkey に対応する値を指定します。 258 * カンマで複数指定で、リクエスト情報でも設定できます。 259 * 260 * @og.rev 3.5.6.0 (2004/06/18) 配列の設定は、arraycopy して取り込みます。 261 * 262 * @param hVals 固定部の値配列(可変長引数) 263 */ 264 public void setHeaderVals( final String... hVals ) { 265 if( hVals != null && hVals.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 266 final int size = hVals.length ; 267 headerVals = new String[size]; 268 System.arraycopy( hVals,0,headerVals,0,size ); 269 } 270 else { 271 headerVals = null; 272 } 273 } 274 275 /** 276 * 雛型帳票に対する、実際の行番号を求めます。 277 * これは、雛型の複数回読みをサポートする為、実際の雛型のrow番号と 278 * DBTableModel から取得すべき row番号が、異なる為です。 279 * オーバーフロー時は、Exception を避ける為、-1 を返します。 280 * 281 * @og.rev 3.5.6.0 (2004/06/18) noDataflag の追加。 282 * @og.rev 3.5.6.3 (2004/07/12) noDataflag の廃止。 283 * @og.rev 3.6.0.4 (2004/10/14) FIRST 雛型時の対応追加。 284 * @og.rev 3.7.0.1 (2005/01/31) ページブレイク処理に対応。 285 * @og.rev 3.8.1.2 (2005/12/19) PAGE_END_CUT用にdataOverフラグを追加 286 * 287 * @param row 固定部の値(オーバーフロー時は、-1 ) 288 * 289 * @return 実際の行番号 290 */ 291 protected int getRealRow( final int row ) { 292 293 // 3.7.0.1 (2005/01/31) ページブレイク処理に対応。 294 int realRow = pageRowCount + row + lineCopyCnt ; 295 if( maxRowCount <= realRow ) { maxRowCount = realRow + 1; } 296 297 if( realRow >= (tableSize-1) ) { // 行番号が最大値と同じ(データは存在) 298 rowOver = true; 299 if( realRow >= tableSize ) { // さらに、データは存在しない。 300 realRow = -1; // 3.5.6.3 (2004/07/12) オーバーフロー 301 dataOver = true; // 3.8.1.2 (2005/12/19) 302 } 303 } 304 305 return realRow ; 306 } 307 308 /** 309 * 指定のキーについて、その値を取得します。 310 * 値の取得方法として、 311 * {@xxx_no} 形式の場合は、DBTableModel から、 312 * {@XXXX} 形式で、かつ、rowOver が false の場合は、ヘッダーから、 313 * {@XXXX} 形式で、かつ、rowOver が true の場合は、フッターから、 314 * 取得します。 315 * rowOver は、{@xxx_no} 形式の番号欄(no)が、DBTableModel のデータ件数よりも 316 * 大きい場合に、セットされます。 317 * 318 * @og.rev 3.5.6.0 (2004/06/18) noDataflag の追加。 319 * @og.rev 3.5.6.3 (2004/07/12) noDataflag の廃止。 320 * @og.rev 3.6.0.0 (2004/09/24) フォーマットエラーの判定(formatErr)を、子クラスから移動します。 321 * @og.rev 3.7.0.1 (2005/01/31) ページブレイク時の処理追加。 322 * @og.rev 3.7.0.2 (2005/02/18) HTML のエスケープ文字対応 323 * @og.rev 3.7.1.1 (2005/05/09) セル内の改行 <br> は、エスケープしない。 324 * @og.rev 3.8.0.0 (2005/06/07) Shift-JIS で中国語を扱う。(Unicodeエスケープ文字は、エスケープしない) 325 * @og.rev 3.8.5.1 (2006/04/28) YKNO を特別扱いする。 326 * @og.rev 6.1.1.0 (2015/01/17) getRendererValue の代わりに、getWriteValue を使うように変更。 327 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 328 * 329 * @param key 指定のキー 330 * 331 * @return 指定のキーの値 332 * @og.rtnNotNull 333 */ 334 protected String getValue( final String key ) { 335 if( pageBreak ) { return ""; } // 3.7.0.1 (2005/01/31) ページブレイク時の処理 336 337 final int sp = key.lastIndexOf( '_' ); 338 if( sp >= 0 ) { 339 try { 340 final int row = Integer.parseInt( key.substring( sp+1 ) ); 341 final int realRow = getRealRow( row ); 342 343 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 344 if( realRow >= 0 && table != null ) { // 6.3.9.0 (2015/11/06) 345 formatErr = false; // 3.6.0.0 (2004/09/24) 346 final int col = table.getColumnNo( key.substring( 0,sp ),false ); 347 if( col < 0 ) { 348 // 超暫定対策:I 変数で、行番号を出力する。 349 if( "I".equals( key.substring( 0,sp ) ) ) { 350 return String.valueOf( realRow+1 ); // 行番号は物理行+1 351 } 352 else { 353 final String errMsg = "カラム名が存在しません:[" + key + "]" ; 354 System.out.println( errMsg ); 355 LogWriter.log( errMsg ); 356 return "" ; 357 } 358 } 359 360 String val = table.getValue( realRow,col ); 361 362 // 3.7.0.1 (2005/01/31) ページブレイク時の処理追加 363 if( pbClmNo == col ) { 364 if( ! rowOver ) { 365 final String val2 = table.getValue( realRow+1,pbClmNo ); // 先読み 366 if( val != null && ! val.equals( val2 ) ) { 367 pageBreak = true; 368 } 369 } 370 return ""; // ページブレイクカラムは、すべて""に変換する。 371 } 372 // 3.7.1.1 (2005/05/09) セル内の改行 <br> は、エスケープしない。 373 val = StringUtil.htmlFilter( val ); 374 val = StringUtil.replace( val,"<br>","<br>" ); 375 // 3.8.0.0 (2005/06/07) Shift-JIS で中国語を扱う。(Unicodeエスケープ文字は、エスケープしない) 376 val = StringUtil.replace( val,"&#","&#" ); // 中国語変換対応 &# は変換しない 377 // 6.1.1.0 (2015/01/17) getRendererValue の代わりに、getWriteValue を使うように変更。 378 return table.getDBColumn( col ).getWriteValue( val ); 379 } 380 } 381 catch( final NumberFormatException ex ) { // 4.0.0 (2005/01/31) 382 final String errMsg = "警告:ヘッダーに'_'カラム名が使用 " 383 + "key=[" + key + "] " 384 + ex.getMessage() ; 385 LogWriter.log( errMsg ); 386 // フォーマットエラーは、何もしない。 387 // 通常のカラム名にアンダーバーが使用されている可能性があるため。 388 } 389 catch( final RuntimeException ex ) { 390 final String errMsg = "カラムデータ取得処理で、エラーが発生しました。 " 391 + "key=[" + key + "] " 392 + ex.getMessage() ; 393 LogWriter.log( errMsg ); 394 // フォーマットエラーは、何もしない。 395 } 396 } 397 398 // 3.8.5.1 (2006/04/28) YKNO を特別扱いする。 399 if( "YKNO".equals( key ) ) { return ykno; } 400 401 String rtnVal ; 402 if( rowOver ) { rtnVal = getFooterValue( key ); } 403 else { rtnVal = getHeaderValue( key ); } 404 405 if( rtnVal == null ) { rtnVal = ""; } 406 return rtnVal ; 407 } 408 409 /** 410 * 固定部のkey に対応する値を取得します。 411 * 412 * @param key String 413 * 414 * @return 固定部の値 415 */ 416 private String getHeaderValue( final String key ) { 417 if( headerKeys == null || 418 headerVals == null || 419 key == null ) { return null; } 420 421 for( int i=0; i<headerKeys.length; i++ ) { 422 if( key.equals( headerKeys[i] ) ) { return headerVals[i]; } 423 } 424 return null; 425 } 426 427 /** 428 * 繰り返し部の終了後に表示する key 部分を指定します。 429 * カンマで複数指定できます。 430 * 431 * @og.rev 3.5.6.0 (2004/06/18) 配列の設定は、arraycopy して取り込みます。 432 * 433 * @param fKeys 繰り返し部の終了後に表示するキー配列(可変長引数) 434 */ 435 public void setFooterKeys( final String... fKeys ) { 436 if( fKeys != null && fKeys.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 437 final int size = fKeys.length ; 438 footerKeys = new String[size]; 439 System.arraycopy( fKeys,0,footerKeys,0,size ); 440 } 441 else { 442 footerKeys = null; 443 } 444 } 445 446 /** 447 * 繰り返し部の終了後に表示する key 部分を取得します。 448 * 449 * @param key String 450 * 451 * @return 繰り返し部の終了後に表示する key 452 */ 453 private String getFooterValue( final String key ) { 454 if( footerKeys == null || 455 footerVals == null || 456 key == null ) { return null; } 457 458 for( int i=0; i<footerKeys.length; i++ ) { 459 if( key.equals( footerKeys[i] ) ) { return footerVals[i]; } 460 } 461 return null; 462 } 463 464 /** 465 * 固定部のkey に対応する値を指定します。 466 * カンマで複数指定で、リクエスト情報でも設定できます。 467 * 468 * @og.rev 3.5.6.0 (2004/06/18) 配列の設定は、arraycopy して取り込みます。 469 * 470 * @param fVals 繰り返し部の終了後に表示する値配列(可変長引数) 471 */ 472 public void setFooterVals( final String... fVals ) { 473 if( fVals != null && fVals.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 474 final int size = fVals.length ; 475 footerVals = new String[size]; 476 System.arraycopy( fVals,0,footerVals,0,size ); 477 } 478 else { 479 footerVals = null; 480 } 481 } 482 483 /** 484 * ボディー部(繰り返し部)がなくなったときに、それ以降を表示するかどうかを指定します。 485 * true では、それ以降を出力しません。 486 * デフォルト "true" (なくなった時点で、出力しない。)です。 487 * 488 * @param pageEndCut 繰り返し部の終了後に継続処理するかどうか (true:処理しない/false:処理する) 489 */ 490 public void setPageEndCut( final boolean pageEndCut ) { 491 this.pageEndCut = pageEndCut ; 492 } 493 494 /** 495 * BufferedReader を、初期化します。 496 * これは、雛型ファイルの終端まで読取り、処理した場合、もう一度 497 * 初めから読み込みなおす処理を行います。 498 * 基本的に、書き込みも初期化する必要があります。 499 * 500 * メモリ上に読み込んで、繰り返し利用するかどうかは、実装依存です。 501 * 502 * @og.rev 3.1.3.0 (2003/04/10) "DEFAULT" エンコーディング名のサポートを廃止。 503 * @og.rev 3.5.5.9 (2004/06/07) FileUtil.getBufferedReader を使用 504 * @og.rev 3.6.0.0 (2004/09/17) 最初のページのみに使用する雛型ファイル名を追加します。 505 * @og.rev 3.6.0.0 (2004/09/24) フォーマットエラーの判定(formatErr)を、子クラスから移動します。 506 * 507 */ 508 protected void initReader() { 509 Closer.ioClose( reader ); // 4.0.0 (2006/01/31) close 処理時の IOException を無視 510 511 if( reader == null && firstTemplateFile != null ) { 512 reader = FileUtil.getBufferedReader(firstTemplateFile,ENCODE); 513 } 514 else { 515 if( formatErr ) { 516 final String errMsg = "Error in HTML File. " + CR 517 + "Excel containing two or more sheets is not supporting." 518 + CR 519 + "or HTML template File is not in '{@xxxx_0}' key word." ; 520 throw new HybsSystemException( errMsg ); 521 } 522 reader = FileUtil.getBufferedReader(templateFile,ENCODE); 523 formatErr = true; // 初期化します。クリアしなければエラー 524 } 525 } 526 527 /** 528 * PrintWriter を、初期化します。 529 * これは、雛型ファイルを終端まで読取り、処理した場合、出力ファイル名を 530 * 変えて、別ファイルとして出力する為のものです。 531 * 基本的に、読取も初期化する必要があります。 532 * 533 * メモリ上に読み込んで、繰り返し利用するかどうかは、実装依存です。 534 * 535 * @og.rev 3.0.0.1 (2003/02/14) ページの最大ページ数の制限を追加。暴走停止用 536 * @og.rev 3.1.3.0 (2003/04/10) "DEFAULT" エンコーディング名のサポートを廃止。 537 * @og.rev 3.5.5.9 (2004/06/07) FileUtil.getPrintWriter メソッドを使用 538 * @og.rev 3.7.0.1 (2005/01/31) ページブレイク処理に対応。 539 * @og.rev 3.8.0.0 (2005/06/07) FileUtil#getPrintWriter を利用。 540 * @og.rev 3.8.5.3 (2006/06/30) EXCEL最大シート数のエラーメッセージを変更。 541 * 542 */ 543 protected void initWriter() { 544 if( writer != null ) { 545 writer.flush(); 546 writer.close(); 547 writer = null; 548 pageCount++ ; 549 if( pageCount >= maxPageCount ) { 550 final String errMsg = "EXCELのページ(シート)が最大ページ数(1000)をオーバーしました。" 551 + CR 552 + "この数は、DB_MAX_ROW_COUNT ではなく、LISTID_999.htmlのオーバーを意味します。" 553 + CR; 554 throw new HybsSystemException( errMsg ); 555 } 556 } 557 558 final int pgCnt = pageCount + 1000; // 桁合わせの為、下3桁を利用します。 559 560 final String subName = String.valueOf( pgCnt ).substring( 1 ); 561 final String filename = htmlFileKey + "_" + subName + ".html" ; 562 563 // 3.8.0.0 (2005/06/07) FileUtil#getPrintWriter を利用。 564 writer = FileUtil.getPrintWriter( new File( htmlDir,filename ),ENCODE ); 565 566 // 3.7.0.1 (2005/01/31) ページブレイク時の処理 567 pageRowCount = maxRowCount ; // そのページの頭のデータ行数をセット 568 pageBreak = false; // pageBreak フラグを元に戻す。 569 } 570 571 /** 572 * ヘッダーフッターのレンデラーデータを設定します。 573 * カンマで複数指定で、リクエスト情報でも設定できます。 574 * 575 * @og.rev 6.1.1.0 (2015/01/17) getRendererValue の代わりに、getWriteValue を使うように変更。 576 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 577 */ 578 protected void setHeaderFooter() { 579 580 DBColumn clm ; 581 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 582 if( headerKeys != null && headerVals != null && resource != null) { 583 for( int i=0; i<headerKeys.length; i++ ) { 584 clm = resource.getDBColumn( headerKeys[i] ); 585 if( clm != null ) { 586 // 6.1.1.0 (2015/01/17) getRendererValue の代わりに、getWriteValue を使うように変更。 587 headerVals[i] = clm.getWriteValue( headerVals[i] ); 588 } 589 } 590 } 591 592 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 593 if( footerKeys != null && footerVals != null && resource != null ) { 594 for( int i=0; i<footerKeys.length; i++ ) { 595 clm = resource.getDBColumn( footerKeys[i] ); 596 if( clm != null ) { 597 // 6.1.1.0 (2015/01/17) getRendererValue の代わりに、getWriteValue を使うように変更。 598 footerVals[i] = clm.getWriteValue( footerVals[i] ); 599 } 600 } 601 } 602 } 603 604 /** 605 * リーダー、ライターの終了処理を行います。 606 * 607 */ 608 private void close() { 609 if( writer != null ) { 610 writer.flush(); 611 writer.close(); 612 writer = null; 613 } 614 Closer.ioClose( reader ); // 4.0.0 (2006/01/31) close 処理時の IOException を無視 615 reader = null; 616 } 617}