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.io;
017
018import java.io.PrintWriter;
019import java.util.List;
020import java.util.Locale;
021import java.util.Map;
022import java.util.Map.Entry;
023
024import org.opengion.hayabusa.common.HybsSystem;
025import org.opengion.hayabusa.common.HybsSystemException;
026import org.opengion.hayabusa.db.DBTableModel;
027import org.opengion.hayabusa.db.DBColumn;
028import org.opengion.fukurou.util.StringUtil;
029import org.opengion.fukurou.util.HybsEntry;
030
031/**
032 * 区切り文字指定(初期値:タブ)ゼロカンマファイルの書き出しクラスです。
033 *
034 * ラベル,名前,データの出力部のみオーバーライドすれば,各種出力フォーマットに合わせた
035 * サブクラスを実現する事が可能です。
036 * ゼロカンマファイルとは、EXCELのゼロサプレス対策として、頭ゼロの文字型データを出力する
037 * 時に、先頭にカンマ(')を付けて、ゼロが削除(見えなくなる)現象を抑止しているファイルです。
038 *
039 * このクラスは,可変長タブ区切り文字ファイルの出力機能を実現しています。
040 *
041 * @og.group ファイル出力
042 *
043 * @version  4.0
044 * @author       Kazuhiko Hasegawa
045 * @since    JDK5.0,
046 */
047public abstract class AbstractTableWriter implements TableWriter {
048        /** このプログラムのVERSION文字列を設定します。   {@value} */
049        private static final String VERSION = "5.7.9.0 (2014/08/08)" ;
050
051        // 5.1.6.0 (2010/05/01) dbType の簡易的な設定
052        /** dbType の簡易的な設定      {@value} */
053        public static final int STRING  = 0;
054        /** dbType の簡易的な設定      {@value} */
055        public static final int NVAR    = 1;
056        /** dbType の簡易的な設定      {@value} */
057        public static final int NUMBER  = 2;
058
059        protected DBTableModel    table         = null;
060        protected DBColumn[]      dbColumn      = null;                 // table に対するカラムオブジェクト(キャッシュ)
061        protected int   numberOfColumns         = -1;                   // 4.0.0 (2005/01/31) 出力対象のカラム数
062        protected int[]                   clmNo         = null;                 // 出力対象のカラム番号配列
063        protected int[]                   dbType        = null;
064
065        private String  separator               = TAB_SEPARATOR;        // 項目区切り文字
066        private String  headerSequence  = HybsSystem.sys( "WRITER_HEADER_SEQUENCE" ) ;
067        private boolean append                  = false;                        // 3.5.4.2 (2003/12/15)
068        private String  lang                    = null;
069        private String  columns                 = null;                         // 4.0.0 (2005/11/30) 外部指定のカラム名
070        private String  encode                  = null;                         // 3.5.4.5 (2004/01/23) エンコード文字列指定
071
072        private boolean useNumber               = true;                         // 3.7.0.2 (2005/02/14) 行番号情報を、出力する(true)/しない(false)を指定
073        private boolean useRenderer             = false;                        // 5.2.1.0 (2010/10/01)
074
075        /**
076         * DBTableModel から 各形式のデータを作成して,PrintWriter に書き出します。
077         * このメソッドは、EXCEL 書き出し時に使用します。
078         *
079         * @see #isExcel()
080         */
081        abstract public void writeDBTable();
082
083        /**
084         * DBTableModel から データを作成して,PrintWriter に書き出します。
085         *
086         * @param       writer PrintWriterオブジェクト
087         */
088        abstract public void writeDBTable( final PrintWriter writer );
089
090        /**
091         * numberOfColumns と DBColumn を初期化します。
092         * 内部的に、DBTableModel、lang , columns を使用して、
093         * numberOfColumns 、dbColumn、clmNo、dbType の値を初期化します。
094         * カラムが1項目もない場合、言語(lnag)が未指定、DBTableModelが未指定(null)
095         * の場合は、false を返します。その場合は、以下の処理は正常に行えません。
096         * データが0件の場合は、処理を行います。通常、ヘッダーのみのファイルを
097         * 作成することになります。(これを雛形として、取込データを登録する事が可能)
098         *
099         * @og.rev 4.0.0.0 (2005/12/31) 外部指定のカラム名を使用
100         * @og.rev 5.1.6.0 (2010/05/01) DbType の初期値を設定する。
101         *
102         * @return      初期化成功:true / 失敗:false
103         */
104        protected boolean createDBColumn() {
105
106                boolean rtnFlag = false;
107                if( lang != null && table != null ) {
108                        if( columns != null ) {
109                                String[] clms = StringUtil.csv2Array( columns );
110                                numberOfColumns = clms.length;
111                                clmNo = new int[numberOfColumns];
112                                for( int i=0; i<numberOfColumns; i++ ) {
113                                        int no = table.getColumnNo( clms[i] );
114                                        clmNo[i] = no;
115                                }
116                        }
117                        else {
118                                numberOfColumns = table.getColumnCount();
119                                clmNo = new int[numberOfColumns];
120                                for( int i=0; i<numberOfColumns; i++ ) {
121                                        clmNo[i] = i;
122                                }
123                        }
124
125                        dbColumn = table.getDBColumns();
126                        rtnFlag = (numberOfColumns > 0);     // カラムが1項目以上あれば成功
127
128                        // 5.1.6.0 (2010/05/01) DbType の初期値を設定する。
129                        dbType = new int[numberOfColumns];
130                        for( int i=0; i<numberOfColumns; i++ ) {
131                                String type = dbColumn[clmNo[i]].getDbType();
132
133                                if( "NVAR".equals( type ) ) {
134                                        dbType[i] = NVAR;
135                                }
136                                else if( "S9".equals( type ) || "R".equals( type )  ) {
137                                        dbType[i] = NUMBER;
138                                }
139                                else {
140                                        dbType[i] = STRING;
141                                }
142                        }
143                }
144                return rtnFlag;
145        }
146
147        /**
148         * PrintWriter に DBTableModelのヘッダー情報を書き込みます。
149         *
150         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
151         *
152         * @param       writer PrintWriterオブジェクト
153         */
154        protected void writeHeader( final PrintWriter writer ) {
155                // ここでは処理を行いません。
156        }
157
158        /**
159         * PrintWriter に DBTableModelのラベル情報を書き込みます。
160         * 第一カラム目は、ラベル情報を示す "#Label" を書き込みます。
161         * この行は、出力形式に無関係に、TableWriter.TAB_SEPARATOR で区切られます。
162         *
163         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
164         * @og.rev 3.7.0.2 (2005/02/14) 行番号情報を、出力する(true)/しない(false)を指定
165         * @og.rev 4.0.0.0 (2005/12/31) 外部指定のカラム名を使用
166         *
167         * @param       table DBTableModelオブジェクト
168         * @param       writer PrintWriterオブジェクト
169         */
170        protected void writeLabel( final DBTableModel table,final PrintWriter writer ) {
171                if( useNumber ) {
172                        writer.print( "#Label" );
173                        writer.print( separator );
174                }
175                else {
176                        writer.print( "#" );
177                }
178
179                for( int i=0; i<numberOfColumns; i++ ) {
180                        if( i != 0 ) { writer.print( separator ); }
181                        int clm = clmNo[i];
182                        writer.print( dbColumn[clm].getLabel() );
183                }
184                writer.println();
185        }
186
187        /**
188         * PrintWriter に DBTableModelの項目名情報を書き込みます。
189         * 第一カラム目は、項目名情報を示す "#Name" を書き込みます。
190         * この行は、出力形式に無関係に、TableWriter.TAB_SEPARATOR で区切られます。
191         *
192         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
193         * @og.rev 3.7.0.2 (2005/02/14) 行番号情報を、出力する(true)/しない(false)を指定
194         *
195         * @param       table DBTableModelオブジェクト
196         * @param       writer PrintWriterオブジェクト
197         */
198        protected void writeName( final DBTableModel table,final PrintWriter writer ) {
199                if( useNumber ) {
200                        writer.print( "#Name" );
201                        writer.print( separator );
202                }
203                else {
204                        writer.print( "#" );
205                }
206
207                for( int i=0; i<numberOfColumns; i++ ) {
208                        if( i != 0 ) { writer.print( separator ); }
209                        int clm = clmNo[i];
210                        writer.print( table.getColumnName(clm) );
211                }
212                writer.println();
213        }
214
215        /**
216         * PrintWriter に DBTableModelのサイズ情報を書き込みます。
217         * 第一カラム目は、サイズ情報を示す "#Size" を書き込みます。
218         * この行は、出力形式に無関係に、TableWriter.TAB_SEPARATOR で区切られます。
219         *
220         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
221         * @og.rev 3.5.5.5 (2004/04/23) DBColumn の size と maxlength の 意味を変更
222         * @og.rev 3.7.0.2 (2005/02/14) 行番号情報を、出力する(true)/しない(false)を指定
223         *
224         * @param       table DBTableModelオブジェクト
225         * @param       writer PrintWriterオブジェクト
226         */
227        protected void writeSize( final DBTableModel table,final PrintWriter writer ) {
228                if( useNumber ) {
229                        writer.print( "#Size" );
230                        writer.print( separator );
231                }
232                else {
233                        writer.print( "#" );
234                }
235
236                for( int i=0; i<numberOfColumns; i++ ) {
237                        if( i != 0 ) { writer.print( separator ); }
238                        int clm = clmNo[i];
239                        writer.print( dbColumn[clm].getTotalSize() );   // 4.0.0 (2005/01/31) メソッド名変更
240                }
241                writer.println();
242        }
243
244        /**
245         * PrintWriter に DBTableModelのクラス名情報を書き込みます。
246         * 第一カラム目は、サイズ情報を示す "#Class" を書き込みます。
247         * この行は、出力形式に無関係に、TableWriter.TAB_SEPARATOR で区切られます。
248         *
249         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
250         *
251         * @param       table DBTableModelオブジェクト
252         * @param       writer PrintWriterオブジェクト
253         */
254        protected void writeClass( final DBTableModel table,final PrintWriter writer ) {
255                if( useNumber ) {
256                        writer.print( "#Class" );
257                        writer.print( separator );
258                }
259                else {
260                        writer.print( "#" );
261                }
262
263                for( int i=0; i<numberOfColumns; i++ ) {
264                        if( i != 0 ) { writer.print( separator ); }
265                        int clm = clmNo[i];
266                        writer.print( dbColumn[clm].getClassName() );
267                }
268                writer.println();
269        }
270
271        /**
272         * PrintWriter に セパレーターを書き込みます。
273         * 第一カラム目は、サイズ情報を示す "#----" を書き込みます。
274         * この行は、出力形式に無関係に、TableWriter.TAB_SEPARATOR で区切られます。
275         *
276         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
277         * @og.rev 3.7.0.2 (2005/02/14) 行番号情報を、出力する(true)/しない(false)を指定
278         *
279         * @param       table DBTableModelオブジェクト
280         * @param       writer PrintWriterオブジェクト
281         */
282        protected void writeSeparator( final DBTableModel table,final PrintWriter writer ) {
283                String sep = "----" ;
284                if( useNumber ) {
285                        writer.print( "#----" );
286                        writer.print( separator );
287                }
288                else {
289                        writer.print( "#" );
290                }
291
292                for( int i=0; i<numberOfColumns; i++ ) {
293                        if( i != 0 ) { writer.print( separator ); }
294                        writer.print( sep );
295                }
296                writer.println();
297        }
298
299        /**
300         * PrintWriter に DBTableModelのテーブル情報を書き込みます。
301         * このクラスでは,データを ダブルコーテーション(")で囲みます。
302         * PrintWriter に DBTableModelのテーブル情報を書き込みます。
303         *
304         * @og.rev 2.0.0.5 (2002/09/30) 先頭が0 でかつ数字タイプ(S9 or R)でない場合に ' を出力するように修正。
305         * @og.rev 2.3.1.2 (2003/01/28) データ出力時に、改行が余分に出される箇所を修正。
306         * @og.rev 3.1.0.0 (2003/03/20) DBColumn から、getDbType() キーを直接取り出す
307         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
308         * @og.rev 3.3.3.1 (2003/07/18) ファイルリード/ライト時に後ろスペースの除去を行います。
309         * @og.rev 3.7.0.2 (2005/02/14) 行番号情報を、出力する(true)/しない(false)を指定
310         * @og.rev 3.8.0.1 (2005/06/17) DBTypeが NVAR の場合は、元のUnicodeに戻します。
311         * @og.rev 5.1.6.0 (2010/05/01) DbType の初期値(dbType)を利用する。
312         * @og.rev 5.2.1.0 (2010/10/01) このメソッドは、abstract 化します。
313         *
314         * @param       table DBTableModelオブジェクト
315         * @param       writer PrintWriterオブジェクト
316         */
317        abstract protected void writeData( final DBTableModel table,final PrintWriter writer ) ;
318//      protected void writeData( final DBTableModel table,final PrintWriter writer ) {
319//              int numberOfRows =      table.getRowCount();
320//
321//              for( int row=0; row<numberOfRows; row++ ) {
322//                      if( useNumber ) {
323//                              writer.print( row+1 );
324//                              writer.print( separator );
325//                      }
326//
327//                      for( int i=0; i<numberOfColumns; i++ ) {
328//                              if( i != 0 ) { writer.print( separator ); }
329//
330//                              int clm = clmNo[i];
331//                              String val = table.getValue(row,clm);
332////                            if( "NVAR".equals( dbColumn[clm].getDbType()) ) {
333//                              if( dbType[i] == NVAR ) {
334//                                      val = StringUtil.getReplaceEscape( val );
335//                              }
336//
337//                              if( val != null && val.length() > 0 && val.charAt(0) == '0' &&
338////                                    NUMBER_TYPE_LIST.indexOf( dbColumn[clm].getDbType() ) < 0 ) {
339//                                      dbType[i] == NUMBER ) {
340//                                              writer.print( "'" );            // 開始日などの 00000000 を文字列タイプで渡す
341//                              }
342//                              writer.print( StringUtil.rTrim( val ) );
343//                      }
344//                      writer.println();
345//              }
346//      }
347
348        /**
349         * DBTableModel をセットします。
350         *
351         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
352         * @og.rev 3.5.4.2 (2003/12/15) lang 引数も同時に設定します。
353         *
354         * @param       table DBTableModelオブジェクト
355         * @param       lang 言語コード
356         */
357        public void setDBTableModel( final DBTableModel table, final String lang ) {
358                this.table = table;
359                this.lang = lang;
360        }
361
362        /**
363         * 内部の DBTableModel を返します。
364         *
365         * @return      DBTableModelオブジェクト
366         */
367        public DBTableModel getDBTableModel() {
368                return table;
369        }
370
371        /**
372         * DBTableModelの出力順をセットします。
373         * Label,Name,Size,Class,Data の各フィールドの頭文字のアルファベットで
374         * 出力順を設定します。
375         *
376         * なお,出力順に指定しない項目は出力されません
377         *
378         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
379         *
380         * @param       hs 出力順 (LNSCD など)
381         */
382        public void setHeaderSequence( final String hs ) {
383                if( hs != null ) { headerSequence = hs ; }
384        }
385
386        /**
387         * DBTableModelの出力順を返します。
388         * Label,Name,Size,Class,Data の各フィールドの頭文字のアルファベットで
389         * 出力順を設定します。
390         *
391         * なお,出力順に指定しない項目は出力されません
392         *
393         * @return      出力順 (LNSCD など)
394         */
395        public String getHeaderSequence() {
396                return headerSequence ;
397        }
398
399        /**
400         * データを書き込む場合の,区切り文字をセットします。
401         *
402         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
403         *
404         * @param       sep 区切り文字
405         */
406        public void setSeparator( final String sep ) {
407                if( sep != null ) { this.separator = sep; }
408        }
409
410        /**
411         * データを書き込む場合の,区切り文字を返します。
412         *
413         * @return      区切り文字
414         */
415        public String getSeparator() {
416                return separator;
417        }
418
419        /**
420         * DBTableModelのデータとして書き込むときに、追加モードで書き込むかどうかを設定します。
421         * 初期値は、false(新規モード)です。
422         *
423         * @og.rev 3.5.4.2 (2003/12/15) 新規追加
424         *
425         * @param       flag    [true:追加モード/false:新規モード]
426         */
427        public void setAppend( final boolean flag ) {
428                append = flag;
429        }
430
431        /**
432         * DBTableModelのデータとして書き込むときに、追加モードで書き込むかどうかを取得します。
433         * 初期値は、false(新規モード)です。
434         *
435         * @og.rev 3.5.4.2 (2003/12/15) 新規追加
436         *
437         * @return      true(追加モード)/false(新規モード)
438         */
439        public boolean isAppend() {
440                return append ;
441        }
442
443        /**
444         * DBTableModelのデータとして読み込むときのシート名を設定します。
445         * 初期値は、"Sheet1" です。
446         * これは、EXCEL追加機能として実装されています。
447         * ※ このクラスでは実装されていません。
448         *
449         * @og.rev 3.5.4.2 (2003/12/15) 新規追加
450         * @og.rev 3.5.4.3 (2004/01/05) 実装廃止(TableWriter_Excel へ移動)
451         *
452         * @param   sheetName シート名
453         */
454        public void setSheetName( final String sheetName ) {
455                String errMsg = "このメソッドは、EXCEL追加機能ですので、使用できません。";
456                throw new UnsupportedOperationException( errMsg );
457        }
458
459        /**
460         * EXCEL雛型参考ファイルのシート名を設定します。
461         * これは、EXCEL追加機能として実装されています。
462         *
463         * EXCELファイルを書き出す時に、雛型として参照するシート名を指定します。
464         * これにより、複数の形式の異なるデータを順次書き出したり(appendモードを併用)する
465         * ことや、シートを指定して新規にEXCELを作成する場合にフォームを設定する事が可能になります。
466         * 初期値は、null(第一シート) です。
467         * ※ このクラスでは実装されていません。
468         *
469         * @og.rev 3.5.4.3 (2004/01/05) 新規追加
470         *
471         * @param   sheetName シート名
472         */
473        public void setRefSheetName( final String sheetName )  {
474                String errMsg = "このメソッドは、EXCEL追加機能ですので、使用できません。";
475                throw new UnsupportedOperationException( errMsg );
476        }
477
478        /**
479         * このクラスが、EXCEL対応機能を持っているかどうかを返します。
480         *
481         * EXCEL対応機能とは、シート名のセット、雛型参照ファイル名のセット、
482         * 書き込み元ファイルのFileオブジェクト取得などの、特殊機能です。
483         * 本来は、インターフェースを分けるべきと考えますが、taglib クラス等の
484         * 関係があり、問い合わせによる条件分岐で対応します。
485         *
486         * @og.rev 3.5.4.3 (2004/01/05) 新規追加
487         *
488         * @return      EXCEL対応機能を持っているかどうか(ここでは、false固定です)
489         */
490        public boolean isExcel() {
491                return false;
492        }
493
494        /**
495         * 出力先ファイル名をセットします。(DIR + Filename)
496         * これは、EXCEL追加機能として実装されています。
497         * ※ このクラスでは実装されていません。
498         * このメソッドでは、必ず、UnsupportedOperationException が、throw されます。
499         *
500         * @og.rev 3.5.4.3 (2004/01/05) 新規作成
501         *
502         * @param   filename EXCEL雛型参考ファイル名
503         */
504        public void setFilename( final String filename ) {
505                String errMsg = "このメソッドは、EXCEL追加機能ですので、使用できません。";
506                throw new UnsupportedOperationException( errMsg );
507        }
508
509        /**
510         * EXCEL雛型参考ファイル名をセットします。(DIR + Filename)
511         * これは、EXCEL追加機能として実装されています。
512         * ※ このクラスでは実装されていません。
513         * このメソッドでは、必ず、UnsupportedOperationException が、throw されます。
514         *
515         * @og.rev 3.5.4.3 (2004/01/05) 新規作成
516         *
517         * @param   filename EXCEL雛型参考ファイル名
518         */
519        public void setRefFilename( final String filename ) {
520                String errMsg = "このメソッドは、EXCEL追加機能ですので、使用できません。";
521                throw new UnsupportedOperationException( errMsg );
522        }
523
524        /**
525         * EXCEL出力時のデフォルトフォント名を設定します。
526         * これは、EXCEL追加機能として実装されています。
527         *
528         * EXCELファイルを書き出す時に、デフォルトフォント名を指定します。
529         * フォント名は、EXCELのフォント名をそのまま使用してください。
530         * 内部的に、POI の org.apache.poi.hssf.usermodel.HSSFFont#setFontName( String )
531         * に設定されます。
532         * 初期値は、システムリソース の TABLE_WRITER_DEFAULT_FONT_NAME です。
533         *
534         * ※ このクラスでは実装されていません。
535         * このメソッドでは、必ず、UnsupportedOperationException が、throw されます。
536         *
537         * @og.rev 3.8.5.3 (2006/08/07) 新規追加
538         *
539         * @param   fontName フォント名
540         */
541        public void setFontName( final String fontName ) {
542                String errMsg = "このメソッドは、EXCEL追加機能ですので、使用できません。";
543                throw new UnsupportedOperationException( errMsg );
544        }
545
546        /**
547         * EXCEL出力時のデフォルトフォントポイント数を設定します。
548         * これは、EXCEL追加機能として実装されています。
549         *
550         * EXCELファイルを書き出す時に、デフォルトポイント数を指定します。
551         * 内部的に、POI の org.apache.poi.hssf.usermodel.HSSFFont#setFontHeightInPoints( short )
552         * に設定されます。
553         * 初期値は、システムリソース の TABLE_WRITER_DEFAULT_FONT_POINTS です。
554         *
555         * ※ このクラスでは実装されていません。
556         * このメソッドでは、必ず、UnsupportedOperationException が、throw されます。
557         *
558         * @og.rev 3.8.5.3 (2006/08/07) 新規追加
559         *
560         * @param       point   フォントポイント数
561         */
562        public void setFontPoint( final short point ) {
563                String errMsg = "このメソッドは、EXCEL追加機能ですので、使用できません。";
564                throw new UnsupportedOperationException( errMsg );
565        }
566
567        /**
568         * 読み取り元ファイルのエンコード文字列を指定します。
569         * ファイルは、BufferedReader で受け取る為、本来は、エンコードは不要ですが、
570         * 固定長ファイルの読み取り時のバイトコード分割時に、指定のエンコードで
571         * 分割する必要があります。(例えば、半角文字は、Shift_JIS では、1バイト)
572         *
573         * @og.rev 3.5.4.5 (2004/01/23) 新規作成
574         *
575         * @param   enc ファイルのエンコード文字列
576         */
577        public void setEncode( final String enc ) {
578                encode = enc;
579        }
580
581        /**
582         * 読み取り元ファイルのエンコード文字列を取得します。
583         * ファイルは、BufferedReader で受け取る為、本来は、エンコードは不要ですが、
584         * 固定長ファイルの読み取り時のバイトコード分割時に、指定のエンコードで
585         * 分割する必要があります。(例えば、半角文字は、Shift_JIS では、1バイト)
586         *
587         * @og.rev 3.5.4.5 (2004/01/23) 新規作成
588         *
589         * @return      ファイルのエンコード文字列
590         */
591        protected String getEncode() {
592                return encode;
593        }
594
595        /**
596         * 行番号情報を、出力する(true)/しない(false)を指定します。
597         *
598         * 通常のフォーマットでは、各行の先頭に行番号を出力します。
599         * これは、#NAME 属性を使用する場合には、必ず出力する必要があります。
600         * (#NAME 属性は、読み取り時には、必須です。)
601         * この、先頭の行番号が不要な場合(つまり、他のシステムへのデータ出力、
602         * このシステムでは、#NAME 属性が出力されないため、読み込みできません。)
603         * この行番号を出力しないようにできます。
604         * 初期値は、true(出力する) です。
605         *
606         * @og.rev 3.7.0.2 (2005/02/14) 新規追加
607         *
608         * @param   useNumber 行番号情報を [true:出力する/false:しない]
609         */
610        public void setUseNumber( final boolean useNumber ) {
611                this.useNumber = useNumber;
612        }
613
614        /**
615         * 行番号情報を、出力する(true)/しない(false)を返します。
616         *
617         * 通常のフォーマットでは、各行の先頭に行番号を出力します。
618         * これは、#NAME 属性を使用する場合には、必ず出力する必要があります。
619         * (#NAME 属性は、読み取り時には、必須です。)
620         * この、先頭の行番号が不要な場合(つまり、他のシステムへのデータ出力、
621         * このシステムでは、#NAME 属性が出力されないため、読み込みできません。)
622         * この行番号を出力しないようにできます。
623         * 初期値は、true(出力する) です。
624         *
625         * @og.rev 3.7.0.2 (2005/02/14) 新規追加
626         *
627         * @return   行番号情報を、出力する(true)/しない(false)
628         */
629        protected boolean isUseNumber() {
630                return useNumber;
631        }
632
633        /**
634         * パラメーターリストをセットします。
635         * 内部は、HybsEntry クラスを持っています。
636         * 引数が、null の場合は、何もしません。
637         * ※ このクラスでは実装されていません。
638         *
639         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
640         *
641         * @param   listParam   パラメーターリスト
642         */
643        public void setParam( final List<HybsEntry> listParam ) {
644                String errMsg = "このメソッドは、XML追加機能ですので、使用できません。";
645                throw new UnsupportedOperationException( errMsg );
646        }
647
648        /**
649         * 出力先ファイルのカラム列を、外部(タグ)よりCSV形式の文字列で指定します。
650         * ただし、指定のカラム名は、DBTableModel上に存在している必要があります。
651         *
652         * @og.rev 4.0.0.0 (2005/11/30) 新規追加
653         *
654         * @param   clms 出力先ファイルのカラム列(カンマ区切り文字)
655         */
656        public void setColumns( final String clms ) {
657                columns = clms ;
658        }
659
660        /**
661         * データの書き込み開始行番号を設定します(初期値:0)。
662         *
663         * TAB区切りテキストやEXCEL等のデータの書き込みの開始行番号を指定します。
664         * 属性名は、行を飛ばす処理ということで、readTable タグと同じ名称です。
665         * ファイルの先頭行が、0行としてカウントしますので、設定値は、読み飛ばす
666         * 件数になります。(1と指定すると、1件読み飛ばし、2行目から読み込みます。)
667         * 行の読み飛ばしと、カラムの読み飛ばし(columns)、refFileURL、refFilename、
668         * refSheetName とともに使用すれば、ある程度のレイアウト設定が可能です。
669         * なお、この機能は、TableWriter_Excel のみに実装します。
670         *
671         * @og.rev 5.7.9.0 (2014/08/08) 新規作成
672         *
673         * @param       skipRowCount 書き込み開始行番号
674         */
675        public void setSkipRowCount( final int skipRowCount ) {
676                if( skipRowCount != 0 ) {
677                        String errMsg = "このメソッドは、TableWriter_Excel のみの機能ですので、使用できません。";
678                        throw new UnsupportedOperationException( errMsg );
679                }
680        }
681
682        /**
683         * 書込処理でコードリソースのラベル変換を行うかどうか[true/false]を指定します。
684         *
685         * コードリソースをそのままの値で出力すると、数字や記号になり何が書かれているのか
686         * 不明になります。
687         * これは、コードリソースをラベルに変換して出力するかどうかを指定します。
688         * 当然、コードはユニークですが、ラベルはユニークになるかどうか保障はされていませんので
689         * TableReader 系で読み込む場合には、リスクが発生します。
690         * また、TableReader 系で読み込む場合にも、ラベルからコードを求める逆変換を行うように、
691         * setUseRenderer メソッドで指定する必要があります。
692         *
693         * 従来は、TableWriter 系に、TableWriter_Renderer 系のクラスを作って対応していましたが、
694         * このメソッドの属性値のフラグで、制御します。
695         *
696         * @og.rev 5.2.1.0 (2010/10/01) 新規作成
697         *
698         * @param       useRenderer     コードリソースのラベル変換を行うかどうか [true:行う/false:行わない]
699         */
700        public void setUseRenderer( final boolean useRenderer ) {
701                this.useRenderer = useRenderer;
702        }
703
704        /**
705         * 書き出し処理でコードリソースのラベル変換を行うかどうかを返します。
706         * 初期値は、false(行わない) です。
707         *
708         * @og.rev 5.2.1.0 (2010/10/01) 新規作成
709         *
710         * @return      ラベル変換を行うかどうか(true:行う/false:行わない)
711         */
712        protected boolean isUseRenderer() {
713                return useRenderer ;
714        }
715
716        /**
717         * データを ダブルコーテーション(")で囲みます。
718         *
719         * この処理では、前後をダブルクオートで囲うため、改行の有無は判定する
720         * 必要はありません。
721         * ダブルクオートを含む場合は、その直前にダブルクオートを強制的に追加します。
722         *
723         * @param        data 元のString文字列
724         *
725         * @return       ダブルコーテーションで囲まれた文字列
726         */
727        protected String quotation( final String data ) {
728                return "\"" + StringUtil.replace( data,"\"","\"\"" ) + "\"" ;
729        }
730
731        /**
732         * データに対して 改行、ダブルクオート等の処理を行います。
733         *
734         * これは、データの前後をダブルクオートで括る quotation(String)と異なり
735         * 前後には、ダブルクオート を追加しません。
736         * ただし、以下の2つの条件で処理を行います。
737         * 1.改行を含む場合は、ダブルクオートを強制的に前後に追加する。
738         * 2.ダブルクオートを含む場合は、その直前にダブルクオートを強制的に追加する。
739         *
740         * @og.rev 5.2.2.0 (2010/11/01) 新規追加
741         *
742         * @param        data 元のString文字列
743         *
744         * @return       改行、ダブルクオート等の処理
745         */
746        protected String quotation2( final String data ) {
747                String rtn = StringUtil.replace( data,"\"","\"\"" );
748                if( rtn != null && rtn.indexOf( HybsSystem.CR ) >= 0 ) {
749                        rtn = "\"" + rtn + "\"" ;
750                }
751
752                return rtn ;
753        }
754
755        /**
756         * keys の整合性チェックを行います。
757         *
758         * キーかkeysMapのどちらかが null の場合は、何もしません。
759         * チェックするキーは、内部で大文字に変換しておきます。
760         * keysMap に登録するキーは、大文字で登録しておいてください。
761         * ここのチェックでは、キーマップに存在しなければ、エラーになります。
762         *
763         * @og.rev 5.6.6.1 (2013/07/12) keys の整合性チェックを行います。
764         *
765         * @param   key チェックするキー文字列(null の場合は、処理しない)
766         * @param   keysMap 利用可能なキーのマップ(大文字に統一)
767         */
768        protected void checkParam( final String key,final Map<String,String> keysMap ) {
769                // key か keysMap かどちらかが null の場合は、処理を行わない。
770                if( key == null || keysMap == null ) { return; }
771
772                String upKey = key.toUpperCase(Locale.JAPAN);
773
774                if( ! keysMap.containsKey( upKey ) ) {
775                        String BR = "<br />" + HybsSystem.CR ;
776                        StringBuilder errMsg = new StringBuilder();
777                        errMsg.append( BR )
778                                  .append( "指定のキーは、この tableWriter では、使用できません。" ).append( BR )
779                                  .append( "  class=[" ).append( getClass().getName() ).append( "]" ).append( BR )
780                                  .append( "  key  =[" ).append( key                              ).append( "]" ).append( BR )
781                                  .append( "  ======== usage keys ======== " ).append( BR ) ;
782                        for( Map.Entry<String, String> entry : keysMap.entrySet() ) {
783                                errMsg.append( "  " ).append( entry.getKey() ).append( " : " )
784                                                                         .append( entry.getValue() ).append( BR ) ;
785                        }
786                        errMsg.append( "  ============================ " ).append( BR );
787
788                        throw new HybsSystemException( errMsg.toString() );
789                }
790        }
791}