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         *   {&#064;xxx_no} 形式の場合は、DBTableModel から、
312         *   {&#064;XXXX} 形式で、かつ、rowOver が false の場合は、ヘッダーから、
313         *   {&#064;XXXX} 形式で、かつ、rowOver が true の場合は、フッターから、
314         * 取得します。
315         * rowOver は、{&#064;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,"&lt;br&gt;","<br>" );
375                                        // 3.8.0.0 (2005/06/07) Shift-JIS で中国語を扱う。(Unicodeエスケープ文字は、エスケープしない)
376                                        val = StringUtil.replace( val,"&amp;#","&#" );  // 中国語変換対応 &amp;# は変換しない
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}