    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.taglib;
    017
    018import org.opengion.fukurou.system.OgRuntimeException ;                 // 6.4.2.0 (2016/01/29)
    019import org.opengion.fukurou.system.OgCharacterException ;               // 6.5.0.1 (2016/10/21)
    020import org.opengion.fukurou.system.ThrowUtil ;                                  // 6.4.2.0 (2016/01/29)
    021import org.opengion.fukurou.util.ErrorMessage;
    022import org.opengion.fukurou.util.StringUtil ;
    023import org.opengion.fukurou.util.ToString;                                              // 6.1.1.0 (2015/01/17)
    024import org.opengion.fukurou.util.FileInfo;                                              // 6.2.0.0 (2015/02/27)
    025import org.opengion.fukurou.util.ArraySet;                                              // 6.4.3.4 (2016/03/11)
    026import org.opengion.hayabusa.common.HybsSystem;
    027import org.opengion.hayabusa.common.HybsSystemException;
    028import org.opengion.hayabusa.common.HybsOverflowException;              // 6.2.2.0 (2015/03/27)
    029import org.opengion.hayabusa.db.DBTableModelUtil;                               // 6.2.1.0 (2015/03/13)
    030import org.opengion.hayabusa.db.DBTableModel;
    031import org.opengion.hayabusa.db.DBColumn;
    032import org.opengion.hayabusa.db.ColumnActionListener;                   // 6.2.2.0 (2015/03/27)
    033import org.opengion.hayabusa.io.TableReader;
    034
    035import static org.opengion.fukurou.util.StringUtil.nval ;
    036import static org.opengion.fukurou.system.HybsConst.BR;                 // 6.1.0.0 (2014/12/26) refactoring
    037
    038import java.util.Locale ;
    039import java.util.List ;                                                                                 // 6.2.5.0 (2015/06/05)
    040import java.util.Set;                                                                                   // 6.4.3.4 (2016/03/11)
    041import java.util.ArrayList ;                                                                    // 6.2.5.0 (2015/06/05)
    042import java.util.Map;                                                                                   // 6.4.6.0 (2016/05/27)
    043import java.util.HashMap ;                                                                              // 6.4.6.0 (2016/05/27)
    044import java.io.File;
    045
    046/**
    047 * 指定のファイルを DBTableModelオブジェクトに読み取るファイル入力タグです。
    048 *
    049 * データ(DBTableModel)と、コントローラ(ReadTableタグ)を与えて、外部からコントロールすることで、
    050 * 各種形式で データ(DBTableModel)を表示させることが できます。
    051 * ReadTableタグ に対して、コマンドを与えることにより、内部のコントローラの実装に対応した
    052 * 形式でデータを作成します。
    053 * すべての読取の初期クラス名を リソースファイルの TABLE_READER_DEFAULT_CLASS で指定可能です。
    054 * その場合、AutoReader を指定すると、Excel と Text(テキスト) を以下の順番で試します。
    055 * Excel,Calc,Text(UnicodeLittle),Text(Windows-31J),Text(UTF-8),Text(EUC-JP),POI
    056 * UTF-8 のTEXTとWindows-31JのTEXTは、ヘッダー部での区別ができないため、正確なTextの自動読取できません。
    057 *
    058 * ※ 6.2.5.0 (2015/06/05) 仕様変更
    059 *    ・AutoReader で、encode を指定すると、Text(encode) を先に試します。
    060 *    ・Textで、encode を指定しない場合は、システム変数の FILE_ENCODE を使用します。
    061 *
    062 * 入力件数を"DB.COUNT" キーでリクエストにセットしています。
    063 *
    064 * @og.formSample
    065 * ●形式：
    066 *     &lt;og:readTable
    067 *         command      = "NEW"
    068 *         fileURL      = "{&#064;USER.ID}"     読取元ディレクトリ名
    069 *         filename     = "{&#064;filename}"    読取元ファイル名
    070 *         encode       = "UnicodeLittle"       読取元ファイルエンコード名
    071 *         maxRowCount  = "10000"               読取最大件数(初期値:0:[無制限])
    072 *     /&gt;
    073 * ●body：なし
    074 *
    075 * ●Tag定義：
    076 *   &lt;og:readTable
    077 *       readerClass        【TAG】実際に読み出すクラス名の略称(TableReader_**** の ****)をセットします
    078 *                                  (初期値:TABLE_READER_DEFAULT_CLASS[={@og.value SystemData#TABLE_READER_DEFAULT_CLASS}])
    079 *       command            【TAG】コマンド (NEW,RENEW)をセットします(初期値:NEW)
    080 *       fileURL            【TAG】読取元ディレクトリ名を指定します(初期値:FILE_URL)
    081 *       filename           【TAG】ファイルを読み出すときのファイル名をセットします (初期値:FILE_FILENAME[=file.xls])
    082 *       encode             【TAG】ファイルを読み出すときのファイルエンコーディング名をセットします(初期値:FILE_ENCODE)
    083 *       skipRowCount       【TAG】(通常は使いません)データの読み飛ばし件数を設定します
    084 *       maxRowCount        【TAG】読取時の最大取り込み件数をセットします (初期値:0:[無制限])
    085 *       errRowCount        【TAG】読取時の最大エラー件数をセットします (初期値:{@og.value #ERROR_ROW_COUNT})(0:[無制限])
    086 *       separator          【TAG】可変長ファイルを読み出すときの項目区切り文字をセットします
    087 *       columns            【TAG】読取元ファイルのカラム列を、外部(タグ)よりCSV形式で指定します
    088 *       omitNames          【TAG】読取対象外のカラム列を、外部(タグ)よりCSV形式で指定します
    089 *       modifyType         【TAG】ファイル取り込み時の モディファイタイプ(A(追加),C(更新),D(削除))を指定します
    090 *       displayMsg         【TAG】query の結果を画面上に表示するメッセージIDを指定します(初期値:VIEW_DISPLAY_MSG[={@og.value SystemData#VIEW_DISPLAY_MSG}]))
    091 *       overflowMsg        【TAG】読取データが最大検索数をオーバーした場合に表示するメッセージリソースIDを指定します (初期値:MSG0007[検索結果が、制限行数を超えましたので、残りはカットされました])
    092 *       notfoundMsg        【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした])
    093 *  ※   sheetName          【TAG】EXCELファイルを読み込むときのシート名を設定します(初期値:指定なし)
    094 *  ※   sheetNos           【TAG】EXCELファイルを読み込むときのシート番号を複数設定できます(初期値:0)
    095 *  ※   sheetConstKeys     【TAG】EXCELファイルを読み込むときの固定値となるカラム名(CSV形式)
    096 *  ※   sheetConstAdrs     【TAG】EXCELファイルを読み込むときの固定値となるアドレス(行-列,行-列,・・・)
    097 *       nullBreakClm       【TAG】カラム列に NULL が現れた時点で読取を中止します(複数Sheetの場合は、次のSheetを読みます)。
    098 *       nullSkipClm        【TAG】カラム列に NULL が現れたレコードは読み飛ばします。
    099 *       useNumber          【TAG】行番号情報を、使用している/していない[true/false]を指定します(初期値:true)
    100 *       useRenderer        【TAG】読取処理でKEY:VAL形式のコードリソースから、KEYを取り出す処理を行うかどうかを指定します(初期値:USE_TABLE_READER_RENDERER[=false])
    101 *       adjustColumns      【TAG】読取元ファイルのデータ変換を行うカラム列をカンマ指定します("*" で全カラム)
    102 *       checkColumns       【TAG】読取元ファイルの整合性チェックを行うカラム列をカンマ指定します("*" で全カラム)
    103 *       nullCheck          【TAG】NULL チェックすべきカラム列をCSV形式(CSV形式)で指定します
    104 *       matchKeys          【TAG】レコードの読取条件指定時のカラム列をCSV形式で指定します 6.4.6.0 (2016/05/27)
    105 *       matchVals          【TAG】レコードの読取条件指定時のカラム列に対応する正規表現データをCSV形式で指定します 6.4.6.0 (2016/05/27)
    106 *       language           【TAG】タグ内部で使用する言語コード[ja/en/zh/…]を指定します
    107 *       stopZero           【TAG】読込件数が０件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する])
    108 *       mainTrans          【TAG】(通常は使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します(初期値:false)
    109 *       tableId            【TAG】(通常は使いません)sessionから所得する DBTableModelオブジェクトの ID
    110 *       scope              【TAG】キャッシュする場合のスコープ[request/page/session/application]を指定します(初期値:session)
    111 *       useSLabel          【TAG】7.0.7.0 (2019/12/13) ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)
    112 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 5.7.7.2 (2014/06/20)
    113 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 5.7.7.2 (2014/06/20)
    114 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない) 5.7.7.2 (2014/06/20)
    115 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない) 5.7.7.2 (2014/06/20)
    116 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
    117 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    118 *   /&gt;
    119 *
    120 * ●使用例
    121 *
    122 *     &lt;og:readTable
    123 *         command        = "NEW"
    124 *         readerClass    = "Text"                テキストファイルの読取
    125 *         modifyType     = "{&#064;modifyType}"  読取時のモディファイタイプ(A,C等)
    126 *         fileURL        = "{&#064;USER.ID}"     読取元ディレクトリ名
    127 *         filename       = "{&#064;filename}"    読取元ファイル名
    128 *         encode         = "Shift_JIS"           読取元ファイルエンコード名
    129 *         maxRowCount    = "10000"               読取最大件数(0:[無制限])
    130 *         columns        = "OYA,KO,HJO,SU,DYSTR,DYEND"   #NAME に対応するカラム列
    131 *         useNumber      = "false"               行番号の存在しないデータを読取ます。
    132 *         adjustColumns  = "OYA,KO,HJO,SU"       データ変換するカラム列("*" で全カラム)
    133 *         checkColumns   = "OYA,KO,HJO,SU"       整合性チェックするカラム列("*" で全カラム)
    134 *         nullCheck      = "OYA,KO,SU"           NULLチェックを実行します("*" で全カラム)
    135 *         stopZero       = "true"                取得0件の場合に以降の処理を停止します
    136 *         skipRowCount   = "4"                   データの読み飛ばし件数(読み込み開始は、この数字＋１行目から)
    137 *     /&gt;
    138 *
    139 * @og.group ファイル入力
    140 *
    141 * @version  4.0
    142 * @author   Kazuhiko Hasegawa
    143 * @since    JDK5.0,
    144 */
    145public class ReadTableTag extends CommonTagSupport {
    146        /** このプログラムのVERSION文字列を設定します。   {@value} */
    147        private static final String VERSION = "7.0.7.0 (2019/12/13)" ;
    148        private static final long serialVersionUID = 707020191213L ;
    149
    150        private static final int ERROR_ROW_COUNT = 200 ;        // 4.0.0 (2007/05/25)
    151
    152        /** command 引数に渡す事の出来る コマンド  新規作成 {@value} */
    153        public static final String CMD_NEW   = "NEW" ;
    154        /** command 引数に渡す事の出来る コマンド  再検索 {@value} */
    155        public static final String CMD_RENEW = "RENEW" ;
    156
    157        // 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    158        private static final Set<String> COMMAND_SET = new ArraySet<>( CMD_NEW , CMD_RENEW );
    159
    160        // 6.2.0.0 (2015/02/27) AutoReaderの対応方法変更。拡張子に応じて、チェック対象を変更する。null は全対象
    161        // 6.2.2.0 (2015/03/27) マクロ付Excel(.xlsm)対応
    162        // 6.2.5.0 (2015/06/05) 文字列配列から、内部クラスに変更
    163        // 6.4.5.1 (2016/04/28) 順番の変更と、CSV対応
    164
    165        private static final List<AutoReaderParam> AUTO_READER_PARAM = new ArrayList<>() ;
    166        static {
    167                AUTO_READER_PARAM.add( new AutoReaderParam( "Excel"     ,       null                    ,       "xls,xlsx,xlsm" ) );
    168                AUTO_READER_PARAM.add( new AutoReaderParam( "CSV"       ,       "Windows-31J"   ,       "csv"                   ) );                    // 6.4.5.1 (2016/04/28) 追加
    169                AUTO_READER_PARAM.add( new AutoReaderParam( "CSV"       ,       "UTF-8"                 ,       "csv"                   ) );                    // 6.4.5.1 (2016/04/28) 追加
    170                AUTO_READER_PARAM.add( new AutoReaderParam( "Text"      ,       "UnicodeLittle" ,       null                    ) );
    171                AUTO_READER_PARAM.add( new AutoReaderParam( "Text"      ,       "Windows-31J"   ,       null                    ) );
    172                AUTO_READER_PARAM.add( new AutoReaderParam( "Text"      ,       "UTF-8"                 ,       null                    ) );
    173                AUTO_READER_PARAM.add( new AutoReaderParam( "Text"      ,       "EUC-JP"                ,       null                    ) );
    174                AUTO_READER_PARAM.add( new AutoReaderParam( "POI"       ,       null                    ,       "ppt,pptx,doc,docx,xls,xlsx,xlsm" ) );          // 6.2.5.0 (2015/06/05) 追加
    175                AUTO_READER_PARAM.add( new AutoReaderParam( "Calc"      ,       null                    ,       "ods"                   ) );                    // 6.4.5.1 (2016/04/28) 位置変更
    176        }
    177
    178        /** 項目区切り文字 */
    179        protected       String  separator               = TableReader.TAB_SEPARATOR;                            // 項目区切り文字 6.2.0.0 (2015/02/27) protected化
    180        private         String  fileURL                 = HybsSystem.sys( "FILE_URL"            );
    181        private         String  filename                = HybsSystem.sys( "FILE_FILENAME"       );              // ファイル名
    182        /** ﾌｧｲﾙｴﾝｺｰﾃﾞｨﾝｸﾞ */
    183        protected       String  encode                  ;                                                                                       // 6.2.5.0 (2015/06/05) ファイルエンコーディング
    184        /** 読取ｸﾗｽ名 */
    185        protected       String  readerClass             ;                                                                                       // 6.2.0.0 (2015/02/27) protected化
    186        /** 最大行 */
    187        protected       int             maxRowCount             ;                                                                                       // 6.2.0.0 (2015/02/27) 初期値を無制限に変更
    188        /** ﾃﾞｨｽﾌﾟﾚｲﾒｯｾｰｼﾞ */
    189        protected       String  displayMsg              = HybsSystem.sys( "VIEW_DISPLAY_MSG" );         // 6.2.0.0 (2015/02/27) protected化
    190        private         String  overflowMsg             = "MSG0007";    // 検索結果が、制限行数を超えましたので、残りはカットされました。
    191        private         String  notfoundMsg             = "MSG0077";    // 対象データはありませんでした。
    192        /** 実行件数 */
    193        protected       int     executeCount    = -1;                   // 検索/実行件数
    194        private         String  modifyType              ;
    195
    196        private transient DBTableModel table    ;
    197        private         String  command                 = CMD_NEW;
    198        private         String  tableId                 = HybsSystem.TBL_MDL_KEY ;
    199        /** ｼｰﾄ名 */
    200        protected       String  sheetName               ;                               // 3.5.4.2 (2003/12/15)
    201        /** シート番号 */
    202        protected       String  sheetNos                ;                               // 5.5.7.2 (2012/10/09) 複数シートを指定できるようにシート番号を指定できるようにする。
    203        /** 固定値となるカラム名 */
    204        protected       String  sheetConstKeys  ;                               // 5.5.8.2 (2012/11/09) 固定値となるカラム名(CSV形式)
    205        /** 固定値となるアドレス */
    206        protected       String  sheetConstAdrs  ;                               // 5.5.8.2 (2012/11/09) 固定値となるアドレス(行-列,行-列,・・・)
    207        /** 取込み条件/Sheet BREAK条件 */
    208        protected       String  nullBreakClm    ;                               // 5.5.8.2 (2012/11/09) 取込み条件/Sheet BREAK条件
    209        /** 行読み飛ばし */
    210        protected       String  nullSkipClm             ;                               // 6.2.3.0 (2015/05/01) 行読み飛ばし
    211
    212        /** 3.5.4.5 (2004/01/23) 外部よりカラム列(CSV形式)を指定できるようにする。    */
    213        protected String columns                        ;                               // 6.2.0.0 (2015/02/27) protected化
    214        /** 6.1.0.0 (2014/12/26) 読取対象外のカラム列を、外部(タグ)より指定する。      */
    215        protected       boolean useNumber               = true;                 // 3.7.0.5 (2005/04/11)
    216        /** stopZero属性 */
    217        protected       boolean stopZero                ;                               // 4.3.7.0 (2009/06/01) stopZero属性追加
    218
    219        private         boolean isMainTrans             = true;                 // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し
    220        /** データの読み飛ばし設定 */
    221        protected       int             skipRowCount    ;                               // 5.1.6.0 (2010/05/01) データの読み飛ばし設定
    222
    223        /** 6.2.2.0 (2015/03/27) ColumnAction インナークラスでパラメータを整理する。       */
    224        protected transient     ColumnAction clmAct     = new ColumnAction();   // 6.3.9.0 (2015/11/06) transient 追加
    225
    226        /** 6.3.6.1 (2015/08/28) DirectTableInsertTag でSQLException発生時にセットする。（暫定対応）     */
    227        protected boolean sqlError              ;                               // 6.3.6.1 (2015/08/28)
    228
    229        /** 7.0.7.0 (2019/12/13) ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false) */
    230        protected boolean               useSLabel       ;
    231
    232        /**
    233         * デフォルトコンストラクター
    234         *
    235         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    236         */
    237        public ReadTableTag() { super(); }              // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    238
    239        /**
    240         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    241         *
    242         * @og.rev 3.0.1.4 (2003/03/17) displayMsg が ０Byteの場合は、件数も表示しないように変更。
    243         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    244         * @og.rev 3.5.4.1 (2003/12/01) 引数の BufferedReader を、InputStream に変更。
    245         * @og.rev 3.5.4.3 (2004/01/05) 引数の InputStream を、 BufferedReader に戻す。
    246         * @og.rev 3.5.6.5 (2004/08/09) 暫定的に、DBTableModelを先行削除します。
    247         * @og.rev 3.6.0.0 (2004/09/24) DBTableModel の先行削除は、scope="session" の場合のみ。
    248         * @og.rev 3.6.0.2 (2004/10/04) 取り込み時チェック用に、checkColumns,adjustColumns 属性追加
    249         * @og.rev 3.6.0.8 (2004/11/19) DBTableModel をセーブする時に、トランザクションチェックを行います。
    250         * @og.rev 3.8.5.3 (2006/08/07) readerClassが "Excel"でエラーが発生したとき、もう一度Defaultで再読取を行います。
    251         * @og.rev 4.0.0.0 (2007/10/12) checkTableColumn 前に、modifyType 設定を行います。
    252         * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( getResource().getMessage ⇒ getResource().getLabel )
    253         * @og.rev 4.3.1.1 (2008/10/08) columnsが指定されている場合は、AutoReader禁止
    254         * @og.rev 4.3.7.0 (2009/06/01) stopZero機能,DB.COUNTリクエストキーへ読込件数セットを追加
    255         * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は、DBTableModelが新規作成された処理でのみ行う。
    256         * @og.rev 5.1.8.0 (2010/07/01) AutoReaderのCalc対応
    257         * @og.rev 5.1.9.0 (2010/08/01) AutoReaderでのExceptionの判定をThrowableに変更
    258         * @og.rev 5.7.1.2 (2013/12/20) tempMsg.toString() ⇒ errMsg 変更
    259         * @og.rev 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加
    260         * @og.rev 6.0.2.5 (2014/10/31) debug=true 時のエラー情報を増やします。
    261         * @og.rev 6.2.0.0 (2015/02/27) TableReader クラスの呼び出し元メソッドの共通化(EXCEL,TEXT)
    262         * @og.rev 6.2.0.0 (2015/02/27) EXCEL出力のparamLevel初期値変更 3:標準推奨 → 4:個人設定可
    263         * @og.rev 6.2.2.0 (2015/03/27) ColumnAction インナークラスでパラメータを整理する。
    264         * @og.rev 6.2.3.0 (2015/05/01) 複数処理を考慮して、例外処理は発行しない。
    265         * @og.rev 6.2.3.0 (2015/05/01) columnsが指定されていても、AutoReader を使えるようにします。
    266         * @og.rev 6.2.4.2 (2015/05/29) エラーを画面に出します。
    267         * @og.rev 6.2.5.0 (2015/06/05) AutoReaderの仕様変更。
    268         * @og.rev 6.3.6.1 (2015/08/28) DirectTableInsertTag でSQLException発生時のみ throwする。
    269         * @og.rev 6.4.2.0 (2016/01/29) StringUtil#ogStackTrace(Throwable) を、ThrowUtil#ogStackTrace(String,Throwable) に置き換え。
    270         * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    271         * @og.rev 6.4.5.1 (2016/04/28) CSV 指定時は、readerClass="Text" , separator="," に、再設定します。
    272         * @og.rev 6.5.0.1 (2016/10/21) Throwable ではなく、OgCharacterException をキャッチして、処理を継続します。
    273         * @og.rev 7.0.4.0 (2019/05/31) encode指定時の処理順序変更
    274         * @og.rev 7.0.5.0 (2019/09/09) OgCharacterExceptionでは、取りこぼしがあるため、OgRuntimeException も継続処理するように変更。
    275         *
    276         * @return      後続処理の指示
    277         */
    278        @Override
    279        public int doEndTag() {
    280                debugPrint();           // 4.0.0 (2005/02/28)
    281                // 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加
    282                if( !useTag() ) { return EVAL_PAGE ; }
    283
    284                int rtnCode = EVAL_PAGE;
    285
    286                if( check( command, COMMAND_SET ) ) {
    287                        useMainTrans( isMainTrans );                    // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し
    288                        startQueryTransaction( tableId );               // 3.6.0.8 (2004/11/19)
    289
    290                        // 3.5.6.5 (2004/08/09) 削除するのは、セッションのオブジェクトでよい。
    291                        // 3.6.0.0 (2004/09/24) 削除するのは、scope="session" の場合のみ。
    292                        if( "session".equals( getScope() ) ) {
    293                                removeSessionAttribute( tableId );
    294                                removeSessionAttribute( HybsSystem.VIEWFORM_KEY );
    295                        }
    296
    297                        // 6.2.5.0 (2015/06/05) AutoReaderの仕様変更。
    298
    299                        // 6.2.0.0 (2015/02/27) EXCEL出力のparamLevel初期値変更 3:標準推奨 → 4:個人設定可
    300                        if( readerClass == null ) {
    301                                readerClass = nval( sys( "TABLE_READER_DEFAULT_CLASS" ) , "AutoReader" );
    302                        }
    303
    304                        // ファイル の読み込み：AutoReader 処理
    305                        // 6.2.5.0 (2015/06/05) AutoReaderParam 内部クラスを使用します。
    306                        final List<AutoReaderParam> readerParam = new ArrayList<>() ;
    307
    308                        if( "AutoReader".equalsIgnoreCase( readerClass ) ) {
    309                                // 4.3.1.1 (2008/10/08)
    310        //                      // 6.2.3.0 (2015/05/01) columnsが指定されていても、AutoReader を使えるようにします。
    311        //                      if( columns != null && columns.length() > 0 ) {
    312        //                              final String errMsg = "columnsが指定されている場合は、readerClass=\"AutoReader\"は使えません";
    313        //                              throw new HybsSystemException( errMsg );        // 4.3.4.4 (2009/01/01)
    314        //                      }
    315                                // 6.2.5.0 (2015/06/05) AutoReaderParam 内部クラスを使用します。
    316                                // 6.5.0.1 (2016/10/21) encode 指定時の優先は、拡張子が、txt か、csv のみとします。
    317        //                      if( encode != null ) { readerParam.add( new AutoReaderParam( "Text" , encode , null ) ); }                              // encode 指定時は優先
    318//                              if( encode != null ) { readerParam.add( new AutoReaderParam( "Text" , encode , "csv,txt,xls" ) ); }             // encode 指定時は優先
    319//                              if( encode != null ) { readerParam.add( new AutoReaderParam( "Text" , encode , "txt,csv,xls" ) ); }             // encode 指定時は優先  7.0.4.0 (2019/05/31) 順序変更
    320                                if( encode != null ) {
    321                                        readerParam.add( new AutoReaderParam( "Text" , encode , "txt,csv,xls" ) );              // encode 指定時は優先  7.0.4.0 (2019/05/31) 順序変更
    322                                        readerParam.add( new AutoReaderParam( "Text" , encode , null          ) );              // 7.1.0.0 (2020/01/20) 拡張子に関係ない分も追加
    323                                }
    324                                readerParam.addAll( AUTO_READER_PARAM );                // 標準のパラメータを追加します。
    325                        }
    326                        else {
    327                                // 6.2.5.0 (2015/06/05) readerClass が "Text" で、encode が null の場合は、FILE_ENCODE を使用する。
    328                                if( "Text".equalsIgnoreCase( readerClass ) && encode == null ) { encode = HybsSystem.sys( "FILE_ENCODE" ); }
    329                                readerParam.add( new AutoReaderParam( readerClass , encode , null ) );
    330                        }
    331
    332                        final String directory = HybsSystem.url2dir( fileURL );
    333                        final File file = new File( directory,filename );
    334
    335                        final String sufix = FileInfo.getSUFIX( file ) ;                // 6.2.3.0 (2015/05/01) 拡張子に応じて、チェックを変更する。
    336
    337                        StringBuilder tempMsg = new StringBuilder( BUFFER_MIDDLE );
    338                        // 6.2.5.0 (2015/06/05) AutoReaderParam 内部クラスを使用します。
    339                        for( final AutoReaderParam arParam : readerParam ) {
    340                                // 6.2.0.0 (2015/02/27) 拡張子に応じて、チェックを変更する。
    341                                if( !arParam.useSufix( sufix ) ) { continue; }          // false:対象外の場合は、次のreaderClassを使う。
    342
    343                                readerClass = arParam.CLASS;
    344                                encode      = arParam.ENCODE;
    345
    346                                // 6.4.5.1 (2016/04/28) CSV 指定時は、readerClass="Text" , separator="," に、再設定します。
    347                                if( "CSV".equalsIgnoreCase( readerClass ) || "CSV".equalsIgnoreCase( sufix ) ) {
    348                                        readerClass = "Text";
    349                                        separator   = ",";
    350                                }
    351
    352                                if( isDebug() ) {
    353                                        final String errMsg = "File=[" + file + "] , class=[" + readerClass + "] , encode=[" + encode + "]" + BR ;
    354                                        jspPrint( errMsg );
    355                                        System.out.println( errMsg );
    356                                }
    357
    358                                try {
    359                                        clmAct.isDebug = isDebug();
    360                                        sqlError = false;       // 6.3.6.1 (2015/08/28) DirectTableInsertTag でSQLException発生時のみ処理する。
    361                                        create( file );         // 6.2.0.0 (2015/02/27) TableReader クラスの呼び出し元メソッドの共通化(EXCEL,TEXT)
    362
    363                                        // 成功すれば、エラーメッセージをクリアして、その場で抜ける。
    364                                        tempMsg = null;
    365                                        break;
    366                                }
    367                                // 6.2.2.0 (2015/03/27) HybsOverflowException処理をタグ側で行う。
    368                                catch( final HybsOverflowException ex ) {
    369                                        // table.setOverflow( true ); は、処理済み。ループから抜けて処理を継続する。
    370                                        tempMsg = null;
    371                                        break;
    372                                }
    373                                // 6.3.6.1 (2015/08/28) DirectTableInsertTag でSQLException発生時のみ処理する。
    374                                catch( final HybsSystemException ex ) {
    375                                        if( sqlError ) { throw ex; }    // SQLException発生時は処理中止
    376                                }
    377                                // 3.8.5.3 (2006/08/07) readerClassが "Excel"でエラーが発生したとき、もう一度Defaultで再読取を行います。
    378                                // 5.1.9.0 (2010/08/01) RuntimeException系のExceptionがキャッチできないため、Throwableで受ける
    379                                // 6.5.0.1 (2016/10/21) Throwable ではなく、OgCharacterException をキャッチして、処理を継続します。
    380                                catch( final OgCharacterException ex ) {
    381                                        tempMsg.append( "File=["  ).append( file )
    382                                                        .append( "] , Class=["   ).append( readerClass )
    383                                                        .append( "] , Encode=["  ).append( encode )
    384                                                        .append( "] Error!"      ).append( CR )
    385                                                        .append( ex.getMessage() ).append( CR ) ;
    386        //                              if( isDebug() ) {
    387        //                                      jspPrint( "<pre>" + tempMsg.toString() + "</pre>" );                            // 6.2.4.2 (2015/05/29) 画面にも出力します。
    388        //                                      tempMsg.append( ThrowUtil.ogStackTrace( ex ) ).append( CR ) ;           // 6.4.2.0 (2016/01/29)
    389        //                              }
    390                                }
    391                                // 7.0.5.0 (2019/09/09) OgCharacterExceptionでは、取りこぼしがあるため、OgRuntimeException も継続処理するように変更。
    392                                catch( final OgRuntimeException ex ) {
    393                                        tempMsg.append( "File=["  ).append( file )
    394                                                        .append( "] , Class=["   ).append( readerClass )
    395                                                        .append( "] , Encode=["  ).append( encode )
    396                                                        .append( "] Error!"      ).append( CR )
    397                                                        .append( ex.getMessage() ).append( CR ) ;
    398
    399                                        // 拡張子が、xls 以外は、処理を停止します。
    400                                        if( !"xls".equalsIgnoreCase( sufix ) ) {
    401                                                tempMsg.append( ThrowUtil.ogStackTrace( ex ) ).append( CR ) ;
    402        //                                      break;          様子見。当面は、止めません。
    403                                        }
    404                                }
    405                                // 6.5.0.1 (2016/10/21) Throwable をキャッチして、処理を中断します。
    406                                catch( final Throwable th ) {
    407                                        tempMsg.append( "File=["  ).append( file )
    408                                                        .append( "] , Class=["   ).append( readerClass )
    409                                                        .append( "] , Encode=["  ).append( encode )
    410                                                        .append( "] Error!"      ).append( CR )
    411                                                        .append( ThrowUtil.ogStackTrace( th ) ).append( CR ) ;          // 6.4.2.0 (2016/01/29)
    412                                        break;
    413                                }
    414                        }
    415
    416                        // 6.2.3.0 (2015/05/01) 複数処理を考慮して、例外処理は発行しない。
    417                        // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
    418                        if( tempMsg == null ) {
    419                                // 6.2.2.0 (2015/03/27) #afterEnd() メソッド 新規作成。
    420                                rtnCode = afterEnd();
    421                        }
    422                        else {                                                          // 最後までエラーがあれば、例外処理を発行します。
    423                                final String errMsg = tempMsg.toString();
    424                                System.err.print( errMsg );
    425                                jspPrint( "<pre>" + errMsg + "</pre>" );                // 6.2.4.0 (2015/05/15) エラーを画面に出します。
    426                                rtnCode = SKIP_PAGE;                                                    // 6.2.4.2 (2015/05/29) エラー時はSKIP
    427                        }
    428                }
    429
    430                return rtnCode ;
    431        }
    432
    433        /**
    434         * #doEndTag() の後続処理を記述します。
    435         *
    436         * これは、サブクラスで、DBTableModel以外の処理を行う場合に、
    437         * 処理内容を分けるために用意します。
    438         *
    439         * @og.rev 6.2.2.0 (2015/03/27) #afterEnd() メソッド 新規作成。
    440         * @og.rev 6.2.4.2 (2015/05/29) executeCount の設定がおかしい。ReadTableTagでは、設定されていなかった。
    441         * @og.rev 6.2.5.0 (2015/06/05) エラー処理は、継承先でも行うので、メソッド化します。
    442         * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。
    443         *
    444         * @return      後続処理の指示
    445         */
    446        protected int afterEnd() {
    447                if( table != null ) {
    448                        // 6.2.4.2 (2015/05/29) executeCount が設定されなくなった件
    449                        executeCount = table.getRowCount();
    450
    451                        // 3.6.0.2 (2004/10/04)
    452                        // 4.0.0.0 (2007/10/12) checkTableColumn 前に、modifyType 設定を行います。
    453
    454                        // 6.2.5.0 (2015/06/05) エラー処理は、継承先でも行うので、メソッド化します。
    455                        final ErrorMessage errMsg = clmAct.getErrorMessage();
    456                        if( !errMsg.isOK() ) {
    457//                              jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg,getResource() ) );
    458                                jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg,getResource(),useSLabel ) );            // 7.0.7.0 (2019/12/13)
    459                                return SKIP_PAGE ;
    460                        }
    461                }
    462
    463                // 3.6.0.8 (2004/11/19) トランザクションチェックを行います。
    464                if( ! commitTableObject( tableId, table ) ) {
    465                        jspPrint( "ReadTableTag Query処理が割り込まれました。DBTableModel は登録しません。" );
    466                        return SKIP_PAGE ;
    467                }
    468
    469                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    470
    471                // 実行件数の表示 command="NEW" のときのみ、displayMsg を表示させます。
    472                // 4.0.0 (2005/11/30) 出力順の変更。一番最初に出力します。
    473                if( CMD_NEW.equals( command ) ) {
    474                        if( executeCount > 0 && displayMsg != null && displayMsg.length() > 0 ) {
    475                                buf.append( executeCount )
    476                                        .append( getResource().getLabel( displayMsg ) )
    477                                        .append( BR );
    478                        }
    479                        else if( executeCount == 0 && notfoundMsg != null && notfoundMsg.length() > 0 ) {
    480                                buf.append( getResource().getLabel( notfoundMsg ) )
    481                                        .append( BR );
    482                        }
    483                }
    484
    485                // 4.3.7.0 (2009/06/01) 読込件数を、"DB.COUNT" キーでリクエストにセットする。
    486                setRequestAttribute( "DB.COUNT"   , String.valueOf( executeCount ) );
    487
    488                // 6.2.0.0 (2015/02/27) オーバーフロー時のメッセージを表示
    489                if( table != null && table.isOverflow() && overflowMsg != null && overflowMsg.length() > 0  ) {
    490                        buf.append( getResource().getLabel( overflowMsg ) )
    491                                .append( BR );
    492                }
    493
    494                jspPrint( buf.toString() );
    495
    496                // 4.3.7.0 (2009/06/01) stopZero機能を追加
    497                return executeCount == 0 && stopZero ? SKIP_PAGE : EVAL_PAGE ;
    498        }
    499
    500        /**
    501         * タグリブオブジェクトをリリースします。
    502         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    503         *
    504         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
    505         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    506         * @og.rev 3.1.3.0 (2003/04/10) FILE_ENCODE から、エンコード情報を取得する。
    507         * @og.rev 3.1.4.0 (2003/04/18) command 属性に、初期値(NEW)を設定する。
    508         * @og.rev 3.5.4.2 (2003/12/15) EXCELのシート名を指定できるように変更。
    509         * @og.rev 3.5.4.5 (2004/01/23) 外部よりカラム列(CSV形式)を指定できるようにする。
    510         * @og.rev 3.6.0.2 (2004/10/04) checkColumns,adjustColumns,allColumnCheck 属性追加
    511         * @og.rev 3.7.0.5 (2005/04/11) useNumber 属性を追加します。
    512         * @og.rev 3.8.0.2 (2005/06/30) nullCheck 属性追加
    513         * @og.rev 3.8.5.3 (2006/08/07) readerClass 属性の初期値をシステムリソースより取得します。
    514         * @og.rev 4.3.7.0 (2009/06/01) stopZero属性追加
    515         * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は、DBTableModelが新規作成された処理でのみ行う。
    516         * @og.rev 5.1.6.0 (2010/05/01) データの読み飛ばし設定 skipRowCount 属性追加
    517         * @og.rev 5.2.1.0 (2010/10/01) 読取処理でコードリソースのラベル変換を行うかどうか useRenderer 属性追加
    518         * @og.rev 5.5.7.2 (2012/10/09) 複数シートを指定できるようにシート番号を指定できるように、sheetNos属性追加
    519         * @og.rev 5.5.8.2 (2012/11/09) 固定値となるカラム名、アドレスの指定のための、sheetConstKeys、sheetConstAdrs属性追加
    520         * @og.rev 5.5.8.2 (2012/11/09) カラム列に NULL が現れた時点で読取を中止する、nullBreakClm属性追加
    521         * @og.rev 6.1.0.0 (2014/12/26) omitNames 属性を追加
    522         * @og.rev 6.2.0.0 (2015/02/27) オーバーフロー時のメッセージを表示
    523         * @og.rev 6.2.0.0 (2015/02/27) EXCEL出力のparamLevel初期値変更 3:標準推奨 → 4:個人設定可
    524         * @og.rev 6.2.2.0 (2015/03/27) ColumnAction インナークラスでパラメータを整理する。
    525         * @og.rev 6.2.3.0 (2015/05/01) 行読み飛ばし nullSkipClm追加
    526         * @og.rev 6.2.5.0 (2015/06/05) ファイルエンコードの初期化を遅らせます。
    527         * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。
    528         */
    529        @Override
    530        protected void release2() {
    531                super.release2();
    532                separator               = TableReader.TAB_SEPARATOR;                    // 項目区切り文字
    533                fileURL                 = HybsSystem.sys( "FILE_URL" );
    534                filename                = HybsSystem.sys( "FILE_FILENAME" );    // ファイル名
    535                encode                  = null;                                                                 // 6.2.5.0 (2015/06/05) ファイルエンコーディング
    536                readerClass             = null;                                                                                                 // 6.2.0.0 (2015/02/27)
    537                maxRowCount             = 0 ;                                                                                                   // 6.2.2.0 (2015/03/27)
    538                displayMsg              = HybsSystem.sys( "VIEW_DISPLAY_MSG" );
    539                overflowMsg             = "MSG0007";    // 検索結果が、制限行数を超えましたので、残りはカットされました。
    540                notfoundMsg             = "MSG0077";    // 対象データはありませんでした。
    541                executeCount    = -1;                   // 検索/実行件数
    542                modifyType              = null;
    543                command                 = CMD_NEW;
    544                table                   = null;
    545                tableId                 = HybsSystem.TBL_MDL_KEY ;
    546                sheetName               = null;         // 3.5.4.2 (2003/12/15)
    547                sheetNos                = null;         // 5.5.7.2 (2012/10/09) 複数シートを指定できるようにシート番号を指定できるようにする。
    548                sheetConstKeys  = null;         // 5.5.8.2 (2012/11/09) 固定値となるカラム名(CSV形式)
    549                sheetConstAdrs  = null;         // 5.5.8.2 (2012/11/09) 固定値となるアドレス(行-列,行-列,・・・)
    550                nullBreakClm    = null;         // 5.5.8.2 (2012/11/09) 取込み条件/Sheet BREAK条件
    551                nullSkipClm             = null;         // 6.2.3.0 (2015/05/01) 行読み飛ばし
    552                columns                 = null;         // 3.5.4.5 (2004/01/23)
    553                useNumber               = true;         // 3.7.0.5 (2005/04/11)
    554                stopZero                = false;        // 4.3.7.0 (2009/06/01) soptZero追加
    555                isMainTrans             = true;         // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し
    556                skipRowCount    = 0;            // 5.1.6.0 (2010/05/01) データの読み飛ばし設定
    557                clmAct                  = new ColumnAction();                                                                   // 6.2.2.0 (2015/03/27)
    558                useSLabel               = false;        // 7.0.7.0 (2019/12/13) ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)
    559        }
    560
    561        /**
    562         * TableReader の実オブジェクトを生成して，BufferedReader に書き込みます。
    563         *
    564         * @og.rev 3.5.4.1 (2003/12/01) 引数の BufferedReader を、InputStream に変更。
    565         * @og.rev 3.5.4.2 (2003/12/15) TableReader のサブクラス名変更。
    566         * @og.rev 3.5.4.2 (2003/12/15) EXCELのシート名を指定できるように変更。
    567         * @og.rev 3.5.4.3 (2004/01/05) 引数の InputStream を、 BufferedReader に戻す。
    568         * @og.rev 3.5.4.5 (2004/01/23) TableReader に、encode を渡すように変更。
    569         * @og.rev 3.5.6.0 (2004/06/18) 各種プラグイン関連付け設定を、システムパラメータ に記述します。
    570         * @og.rev 3.7.0.5 (2005/04/11) useNumber 属性を追加します。
    571         * @og.rev 4.0.0.0 (2005/01/31) キーの指定を、TableReader. から、TableReader_ に変更します。
    572         * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更
    573         * @og.rev 5.1.6.0 (2010/05/01) データの読み飛ばし設定 skipRowCount 属性追加
    574         * @og.rev 5.2.1.0 (2010/10/01) 読取処理でコードリソースのラベル変換を行うかどうか設定 useRenderer 属性追加
    575         * @og.rev 5.5.7.2 (2012/10/09) 複数シートを指定できるようにシート番号を指定できるように、sheetNos属性追加
    576         * @og.rev 5.5.8.2 (2012/11/09) 固定値となるカラム名、アドレスの指定のための、sheetConstKeys、sheetConstAdrs属性追加
    577         * @og.rev 5.5.8.2 (2012/11/09) カラム列に NULL が現れた時点で読取を中止する、nullBreakClm属性追加
    578         * @og.rev 6.0.4.0 (2014/11/28) NullPointerException が発生するので、事前にチェックします。
    579         * @og.rev 6.2.0.0 (2015/02/27) TableReader クラスの呼び出し元メソッドの共通化(EXCEL,TEXT)
    580         * @og.rev 6.2.2.0 (2015/03/27) ColumnAction インナークラスでパラメータを整理する。
    581         * @og.rev 6.2.2.0 (2015/03/27) ColumnActionListener 対応。
    582         * @og.rev 6.2.3.0 (2015/05/01) 行読み飛ばし nullSkipClm追加
    583         * @og.rev 6.4.1.2 (2016/01/22) setColumnActionListener は、内部処理が走るため、他の設定が終わってから呼び出す。
    584         * @og.rev 6.4.3.3 (2016/03/04) HybsSystem.newInstance(String,String) への置き換え。
    585         *
    586         * @param       file    出力するFileオブジェクト
    587         */
    588        protected void create( final File file )  {
    589                table = DBTableModelUtil.newDBTable();                  // 6.2.1.0 (2015/03/13)
    590
    591                /**
    592                 * ColumnActionListenerインターフェースの内部無名クラス
    593                 *
    594                 * @og.rev 6.2.2.0 (2015/03/27) ColumnActionListener 対応。
    595                 *
    596                 * @param names カラム名配列
    597                 */
    598                final ColumnActionListener listener = new ColumnActionListener() {
    599                        private DBColumn[] dbClms ;                             // 6.3.9.1 (2015/11/27) 修飾子を、なし → private に変更。
    600
    601                        /**
    602                         * カラム名の配列が設定された場合に、呼び出されます。
    603                         *
    604                         * @og.rev 6.2.2.0 (2015/03/27) ColumnActionListener 対応。
    605                         *
    606                         * @param names カラム名配列
    607                         */
    608                        @Override
    609                        public void columnNames( final String[] names ) {
    610                                final String[] nms = clmAct.makeNames( names );
    611                                table.init( nms.length );
    612                                dbClms = new DBColumn[nms.length];
    613                                for( int no=0; no<nms.length; no++ ) {
    614                                        dbClms[no] = getDBColumn( nms[no] );
    615                                        table.setDBColumn( no,dbClms[no] );
    616                                }
    617                        }
    618
    619                        /**
    620                         * １行分のデータが設定された場合に、呼び出されます。
    621                         *
    622                         * @og.rev 6.2.2.0 (2015/03/27) ColumnActionListener 対応。
    623                         * @og.rev 6.4.6.0 (2016/05/27) レコードの読取条件指定を追加。条件に一致しなければ、null が返されます。
    624                         *
    625                         * @param   vals    文字列値の１行分の配列
    626                         * @param   rowNo   行番号(0～)
    627                         */
    628                        @Override
    629                        public void values( final String[] vals, final int rowNo ) {
    630                                if( maxRowCount > 0 && rowNo > maxRowCount ) {          // 読み取り件数オーバーフロー
    631                                        table.setOverflow( true );
    632                                        throw new HybsOverflowException();
    633                                }
    634
    635                                final String[] newVals = clmAct.clmAction( vals , dbClms , rowNo );
    636                                // 6.4.6.0 (2016/05/27) レコードの読取条件指定を追加。条件に一致しなければ、null が返されます。
    637                                if( newVals != null ) {
    638                                        table.addColumnValues( newVals,modifyType,true );       // 値配列、変更タイプ、書込許可
    639                                }
    640                        }
    641                };
    642                final TableReader reader = HybsSystem.newInstance( "TableReader_" , readerClass );      // 3.5.5.3 (2004/04/09)
    643
    644                reader.setSeparator( separator );
    645                reader.setColumns( columns );                                   // 3.5.4.5 (2004/01/23) 、6.2.0.0 (2015/02/27) 削除
    646                reader.setUseNumber( useNumber );                               // 3.7.0.5 (2005/04/11)
    647                reader.setSkipRowCount( skipRowCount );                 // 5.1.6.0 (2010/05/01)
    648                reader.setDebug( isDebug() );                                   // 5.5.7.2 (2012/10/09) デバッグ情報を出力するかどうかを指定
    649                // 6.2.0.0 (2015/02/27) EXCELでない場合でも、メソッドは呼び出す。(空振りします)
    650                reader.setSheetName( sheetName );                       // 3.5.4.2 (2003/12/15)
    651                reader.setSheetNos( sheetNos );                         // 5.5.7.2 (2012/10/09) 複数シートを指定できるようにシート番号を指定できるようにする。
    652                reader.setSheetConstData( sheetConstKeys,sheetConstAdrs ) ;             // 5.5.8.2 (2012/11/09) 固定値となるカラム名、アドレスの指定
    653                reader.setNullBreakClm( nullBreakClm ) ;        // 5.5.8.2 (2012/11/09) 取込み条件/Sheet BREAK条件
    654                reader.setNullSkipClm( nullSkipClm ) ;          // 6.2.3.0 (2015/05/01) 行読み飛ばし
    655                // 6.4.1.2 (2016/01/22) setColumnActionListener は、内部処理が走るため、他の設定が終わってから呼び出す。
    656                reader.setColumnActionListener( listener );             // 6.2.2.0 (2015/03/27)
    657
    658                reader.readDBTable( file,encode );                      // 6.2.0.0 (2015/02/27) 追加
    659        }
    660
    661        /**
    662         * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
    663         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
    664         *
    665         * @og.tag
    666         * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に
    667         * 渡す場合に、通常は、session を利用します。その場合の登録キーです。
    668         * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、
    669         * この tableId 属性を利用して、メモリ空間を分けます。
    670         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
    671         *
    672         * @param       id テーブルID (sessionに登録する時のID)
    673         */
    674        public void setTableId( final String id ) {
    675                tableId = nval( getRequestParameter( id ), tableId );
    676        }
    677
    678        /**
    679         * 【TAG】可変長ファイルを作成するときの項目区切り文字をセットします。
    680         *
    681         * @og.tag 可変長ファイルを作成するときの項目区切り文字をセットします。
    682         *
    683         * @param   separator 項目区切り文字
    684         */
    685        public void setSeparator( final String separator ) {
    686                this.separator = nval( getRequestParameter( separator ),this.separator );
    687        }
    688
    689        /**
    690         * 【TAG】読取元ディレクトリ名を指定します
    691         *              (初期値:FILE_URL[={@og.value SystemData#FILE_URL}])。
    692         *
    693         * @og.tag
    694         * この属性で指定されるディレクトリより、ファイルを読取ます。
    695         * 指定方法は、通常の fileURL 属性と同様に、先頭が、'/' (UNIX) または、２文字目が、
    696         * ":" (Windows)の場合は、指定のURLそのままのディレクトリに、そうでない場合は、
    697         * fileURL = "{&#064;USER.ID}" と指定すると、FILE_URL 属性で指定のフォルダの下に、
    698         * さらに、各個人ID別のフォルダを作成して、そこを操作します。
    699         * (初期値:システム定数のFILE_URL[={@og.value SystemData#FILE_URL}])。
    700         *
    701         * @og.rev 4.0.0.0 (2005/01/31) StringUtil.urlAppend メソッドの利用
    702         * @og.rev 4.0.0.0 (2007/11/20) 指定されたディレクトリ名の最後が"\"or"/"で終わっていない場合に、"/"を付加する。
    703         * @og.rev 6.4.2.1 (2016/02/05) URLの最後に、"/" を追加する処理を廃止。
    704         *
    705         * @param       url 読取元ディレクトリ名
    706         * @see         org.opengion.hayabusa.common.SystemData#FILE_URL
    707         */
    708        public void setFileURL( final String url ) {
    709                final String furl = nval( getRequestParameter( url ),null );
    710                if( furl != null ) {
    711                        fileURL = StringUtil.urlAppend( fileURL,furl );
    712                }
    713        }
    714
    715        /**
    716         * 【TAG】ファイルを作成するときのファイル名をセットします
    717         *              (初期値:FILE_FILENAME[={@og.value SystemData#FILE_FILENAME}])。
    718         *
    719         * @og.tag ファイルを作成するときのファイル名をセットします。
    720         * (初期値:システム定数のFILE_FILENAME[={@og.value SystemData#FILE_FILENAME}])。
    721         *
    722         * @param   filename ファイル名
    723         * @see         org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK
    724         */
    725        public void setFilename( final String filename ) {
    726                this.filename = nval( getRequestParameter( filename ),this.filename );
    727        }
    728
    729        /**
    730         * 【TAG】ファイルを作成するときのファイルエンコーディング名をセットします
    731         *              (初期値:FILE_ENCODE[={@og.value SystemData#FILE_ENCODE}])。
    732         *
    733         * @og.tag
    734         * readerClass="AutoReader" の場合、ここで設定した encode が優先されます。
    735         * readerClass="Text" の場合、encode が指定されていない場合は、初期値 の FILE_ENCODE が使用されます
    736         *
    737         * Shift_JIS,MS932,Windows-31J,UTF-8,ISO-8859-1,UnicodeLittle
    738         * (初期値:システム定数のFILE_ENCODE[={@og.value SystemData#FILE_ENCODE}])。
    739         *
    740         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 エンコードの取得方法変更
    741         * @og.rev 3.1.3.0 (2003/04/10) FILE_ENCODE から、エンコード情報を取得する。
    742         *
    743         * @param   enc ファイルエンコーディング名
    744         * @see     <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a>
    745         * @see         org.opengion.hayabusa.common.SystemData#FILE_ENCODE
    746         */
    747        public void setEncode( final String enc ) {
    748                encode = nval( getRequestParameter( enc ),encode );
    749        }
    750
    751        /**
    752         * 【TAG】実際に読み出すクラス名の略称(TableReader_**** の ****)をセットします
    753         *              (初期値:TABLE_READER_DEFAULT_CLASS[={@og.value SystemData#TABLE_READER_DEFAULT_CLASS}])。
    754         *
    755         * @og.tag
    756         * 実際に読み出すクラス名(の略称)をセットします。
    757         * これは、org.opengion.hayabusa.io 以下の TableReader_**** クラスの **** を
    758         * 与えます。これらは、TableReader インターフェースを継承したサブクラスです。
    759         * 属性クラス定義の {@link org.opengion.hayabusa.io.TableReader TableReader} を参照願います。
    760         * {@og.doc03Link readerClass TableReader_**** クラス}
    761         * @og.rev 3.1.3.0 (2003/04/10) FILE_ENCODE から、エンコード情報を取得する。
    762         *
    763         * "AutoReader" は特別な名前で、Excel と Text(テキスト) を以下の順番で試します。
    764         * Excel,Calc,Text(UnicodeLittle),Text(Windows-31J),Text(Windows-31J),Text(UTF-8),Text(EUC-JP)
    765         * Excel については、拡張子を自動判定して、(xlsx か xls) 適切な処理を行います。
    766         * 従来からの 拡張子のみ、xls のテキストファイルは、#NAME を見つけることができないため、エラーになり、
    767         * 次のText読み取りにゆだねられます。
    768         * UTF-8 のTEXTとWindows-31JのTEXTは、ヘッダー部での区別ができないため、java.nio.file.Files と Pathを
    769         * 使用した読み取り方式に変更しています。
    770         * "AutoReader" に設定した場合は、上記の様に、encode を順番に確かめるため、encode属性の指定は無視されます。
    771         *              (初期値:TABLE_READER_DEFAULT_CLASS[={@og.value SystemData#TABLE_READER_DEFAULT_CLASS}])。
    772         *
    773         * @og.rev 6.2.1.0 (2015/03/13) Default廃止に伴い、Defaultが指定された場合は、Textに置き換える。
    774         *
    775         * @param   readerCls クラス名(の略称)
    776         * @see         org.opengion.hayabusa.io.TableReader  TableReaderのサブクラス
    777         */
    778        public void setReaderClass( final String readerCls ) {
    779                readerClass = nval( getRequestParameter( readerCls ),readerClass );
    780
    781                // 6.2.1.0 (2015/03/13) 互換性の為。
    782                if( "Default".equals( readerClass ) ) { readerClass = "Text" ; }
    783        }
    784
    785        /**
    786         * 【TAG】読取時の最大取り込み件数をセットします(初期値:0:無制限)。
    787         *
    788         * @og.tag
    789         * DBTableModelのデータとして登録する最大件数をこの値に設定します。
    790         * サーバーのメモリ資源と応答時間の確保の為です。
    791         * 0 をセットすると、無制限になります。
    792         * (初期値:0:無制限)
    793         *
    794         * @og.rev 5.5.8.5 (2012/11/27) 0を無制限として処理します。
    795         * @og.rev 6.2.2.0 (2015/03/27) 初期値を、無制限に変更
    796         *
    797         * @param   count 最大件数
    798         */
    799        public void setMaxRowCount( final String count ) {
    800                maxRowCount = nval( getRequestParameter( count ),maxRowCount );
    801        }
    802
    803        /**
    804         * 【TAG】読取時の最大エラー件数をセットします (初期値:{@og.value #ERROR_ROW_COUNT})。
    805         *
    806         * @og.tag
    807         * DBTableModelのデータチェックを行う場合、エラーの最大件数をこの値に設定します。
    808         * エラー最大件数がこの値を超えると、処理を打ち切ります。
    809         * 0 をセットすると、無制限になります。
    810         * (初期値:{@og.value #ERROR_ROW_COUNT})。
    811         *
    812         * @og.rev 6.2.2.0 (2015/03/27) 読取時の最大エラー件数(errRowCount) を新規追加
    813         *
    814         * @param   count 最大件数
    815         */
    816        public void setErrRowCount( final String count ) {
    817                clmAct.errRowCount = nval( getRequestParameter( count ),ERROR_ROW_COUNT );
    818        }
    819
    820        /**
    821         * 【TAG】コマンド (NEW,RENEW)をセットします(初期値:NEW)。
    822         *
    823         * @og.tag
    824         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
    825         * フィールド定数値のいづれかを、指定できます。
    826         * 何も設定されない、または、null の場合は、"NEW" が初期値にセットされます。
    827         *
    828         * @param       cmd コマンド (public static final 宣言されている文字列)
    829         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ReadTableTag.CMD_NEW">コマンド定数</a>
    830         */
    831        public void setCommand( final String cmd ) {
    832                final String cmd2 = getRequestParameter( cmd );
    833                if( cmd2 != null && cmd2.length() > 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); }
    834        }
    835
    836        /**
    837         * 【TAG】query の結果を画面上に表示するメッセージIDを指定します
    838         *              (初期値:VIEW_DISPLAY_MSG[={@og.value SystemData#VIEW_DISPLAY_MSG}])。
    839         *
    840         * @og.tag
    841         * ここでは、検索結果の件数や登録された件数をまず出力し、
    842         * その次に、ここで指定したメッセージをリソースから取得して
    843         * 表示します。
    844         * 件数を表示させる場合は、displayMsg = "MSG0033"[　件検索しました] をセットしてください。
    845         * 表示させたくない場合は, displayMsg = "" をセットしてください。
    846         * (初期値:システム定数のVIEW_DISPLAY_MSG[={@og.value SystemData#VIEW_DISPLAY_MSG}])。
    847         *
    848         * @og.rev 6.2.0.0 (2015/02/27) リクエスト変数を使用できるように修正。
    849         *
    850         * @param       id 処理結果表示メッセージID
    851         */
    852        public void setDisplayMsg( final String id ) {
    853                final String ids = getRequestParameter( id );
    854                if( ids != null ) { displayMsg = ids; }
    855        }
    856
    857        /**
    858         * 【TAG】読取データが最大検索数をオーバーした場合に表示するメッセージリソースIDを指定します
    859         *              (初期値:MSG0007[検索結果が、制限行数を超えましたので、残りはカットされました])。
    860         *
    861         * @og.tag
    862         * 読取結果が、maxRowCount で設定された値より多い場合、何らかのデータは読取されず
    863         * 切り捨てられたことになります。
    864         * ここでは、displayMsg を表示した後、必要に応じて、このメッセージを表示します。
    865         * 表示させたくない場合は, overflowMsg = "" をセットしてください。
    866         * 初期値は、MSG0007[検索結果が、制限行数を超えましたので、残りはカットされました]です。
    867         *
    868         * @og.rev 6.2.0.0 (2015/02/27) オーバーフロー時のメッセージを表示
    869         *
    870         * @param       id 検索数オーバー時メッセージID
    871         */
    872        public void setOverflowMsg( final String id ) {
    873                final String ids = getRequestParameter( id );
    874                if( ids != null ) { overflowMsg = ids; }
    875        }
    876
    877        /**
    878         * 【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした])。
    879         *
    880         * @og.tag
    881         * ここでは、検索結果がゼロ件の場合のみ、特別なメッセージを表示させます。
    882         * 従来は、displayMsg と兼用で、『0　件検索しました』という表示でしたが、
    883         * displayMsg の初期表示は、OFF になりましたので、ゼロ件の場合のみ別に表示させます。
    884         * 表示させたくない場合は, notfoundMsg = "" をセットしてください。
    885         * 初期値は、MSG0077[対象データはありませんでした]です。
    886         *
    887         * @param       id ゼロ件時表示メッセージID
    888         */
    889        public void setNotfoundMsg( final String id ) {
    890                final String ids = getRequestParameter( id );
    891                if( ids != null ) { notfoundMsg = ids; }
    892        }
    893
    894        /**
    895         * 【TAG】ファイル取り込み時の 更新タイプ [A:追加/C:更新/D:削除]を指定します。
    896         *
    897         * @og.tag
    898         * ファイル読み込み時に、そのデータをA(追加)、C(更新)、D(削除)の
    899         * 更新タイプをつけた状態にします。
    900         * その状態で、そのまま、update する事が可能になります。
    901         *
    902         * @param   type 更新タイプ [A:追加/C:更新/D:削除]
    903         */
    904        public void setModifyType( final String type ) {
    905                modifyType = getRequestParameter( type );
    906        }
    907
    908        /**
    909         * 【TAG】EXCELファイルを読み込むときのシート名を設定します(初期値:指定なし)。
    910         *
    911         * @og.tag
    912         * EXCELファイルを読み込む時に、シート名を指定します。これにより、複数の形式の
    913         * 異なるデータを順次読み込むことや、シートを指定して読み取ることが可能になります。
    914         * sheetNos と sheetName が同時に指定された場合は、sheetNos が優先されます。エラーにはならないのでご注意ください。
    915         * 初期値は、指定なしです。
    916         *
    917         * @og.rev 3.5.4.2 (2003/12/15) 新規追加
    918         *
    919         * @param   sheet EXCELファイルのシート名
    920         * @see         #setSheetNos( String )
    921         */
    922        public void setSheetName( final String sheet ) {
    923                sheetName = nval( getRequestParameter( sheet ),sheetName );
    924        }
    925
    926        /**
    927         * 【TAG】EXCELファイルを読み込むときのシート番号を指定します(初期値:0)。
    928         *
    929         * @og.tag
    930         * EXCEL読み込み時に複数シートをマージして取り込みます。
    931         * シート番号は、0 から始まる数字で表します。
    932         * ヘッダーは、最初のシートのカラム位置に合わせます。（ヘッダータイトルの自動認識はありません。）
    933         * よって、指定するシートは、すべて同一レイアウトでないと取り込み時にカラムのずれが発生します。
    934         *
    935         * シート番号の指定は、CSV形式で、複数指定できます。また、N-M の様にハイフンで繋げることで、
    936         * N 番から、M 番のシート範囲を一括指定可能です。また、"*" による、全シート指定が可能です。
    937         * これらの組み合わせも可能です。（ 0,1,3,5-8,10-* ）
    938         * ただし、"*" に関しては例外的に、一文字だけで、すべてのシートを表すか、N-* を最後に指定するかの
    939         * どちらかです。途中には、"*" は、現れません。
    940         * シート番号は、重複(1,1,2,2)、逆転(3,2,1) での指定が可能です。これは、その指定順で、読み込まれます。
    941         * sheetNos と sheetName が同時に指定された場合は、sheetNos が優先されます。エラーにはならないのでご注意ください。
    942         *
    943         * 初期値は、0（第一シート） です。
    944         *
    945         * @og.rev 5.5.7.2 (2012/10/09) 新規追加
    946         *
    947         * @param   sheet EXCELファイルのシート番号（0から始まる）
    948         * @see         #setSheetName( String )
    949         */
    950        public void setSheetNos( final String sheet ) {
    951                sheetNos = nval( getRequestParameter( sheet ),sheetNos );
    952                if( sheetNos != null && sheetNos.length() > 0 ) {
    953                        boolean errFlag = false;
    954                        for( int i=0; i<sheetNos.length(); i++ ) {
    955                                final char ch = sheetNos.charAt(i);
    956                                if( ch == '-' || ch == ',' ) { continue; }
    957                                if( ch == '*' && ( i==0 || i==sheetNos.length()-1 ) ) { continue; }
    958                                if( ch < '0' || ch > '9' ) { errFlag = true; break; }
    959                        }
    960                        if( errFlag ) {
    961                                final String errMsg = "sheetNos の指定を見直してください。sheetNos=[" + sheetNos + "]";
    962                                throw new HybsSystemException( errMsg );
    963                        }
    964                }
    965        }
    966
    967        /**
    968         * 【TAG】EXCELファイルを読み込むときのシート単位の固定値を設定するためのカラム名を指定します。
    969         *
    970         * @og.tag
    971         * カラム名は、CSV形式で指定します。
    972         * これにより、シートの一か所に書かれている情報を、DBTableModel のカラムに固定値として
    973         * 設定することができます。
    974         * 例として、DB定義書で、テーブル名をシートの全レコードに設定したい場合などに使います。
    975         * このメソッドは、isExcel() == true の場合のみ利用されます。
    976         *
    977         * @og.rev 5.5.8.2 (2012/11/09) 新規追加
    978         *
    979         * @param   constKeys 固定値となるカラム名 (CSV形式)
    980         * @see         #setSheetConstAdrs( String )
    981         */
    982        public void setSheetConstKeys( final String constKeys ) {
    983                sheetConstKeys = nval( getRequestParameter( constKeys ),null );
    984        }
    985
    986        /**
    987         * 【TAG】EXCELファイルを読み込むときのシート単位の固定値を設定するためのカラム名に対応するアドレスを指定します。
    988         *
    989         * @og.tag
    990         * アドレスは、EXCEL上の行-列をCSV形式で指定します。
    991         * 行列は、EXCELオブジェクトに準拠するため、０から始まる整数です。
    992         * 0-0 ⇒ A1 , 1-0 ⇒ A2 , 0-1 ⇒ B1 になります。
    993         * これにより、シートの一か所に書かれている情報を、DBTableModel のカラムに固定値として
    994         * 設定することができます。
    995         * 例として、DB定義書で、テーブル名をシートの全レコードに設定したい場合などに使います。
    996         * このメソッドは、isExcel() == true の場合のみ利用されます。
    997         *
    998         * 5.7.6.3 (2014/05/23) より、
    999         *   ①EXCEL表記に準拠した、A1,A2,B1 の記述も処理できるように対応します。
    1000         *     なお、A1,A2,B1 の記述は、必ず、英字1文字＋数字 にしてください。(A～Zまで)
    1001         *   ②処理中のEXCELシート名をカラムに割り当てるために、"SHEET" という記号に対応します。
    1002         * 例えば、sheetConstKeys="CLM,LANG,NAME" とし、sheetConstAdrs="0-0,A2,SHEET" とすると、
    1003         * NAMEカラムには、シート名を読み込むことができます。
    1004         * これは、内部処理の簡素化のためです。
    1005         *
    1006         * ちなみに、EXCELのセルに、シート名を表示させる場合の関数は、下記の様になります。
    1007         * =RIGHT(CELL("filename",$A$1),LEN(CELL("filename",$A$1))-FIND("]",CELL("filename",$A$1)))
    1008         *
    1009         * @og.rev 5.5.8.2 (2012/11/09) 新規追加
    1010         *
    1011         * @param   constAdrs 固定値となるアドレス (行-列,行-列,・・・)
    1012         * @see         #setSheetConstKeys( String )
    1013         */
    1014        public void setSheetConstAdrs( final String constAdrs ) {
    1015                sheetConstAdrs = nval( getRequestParameter( constAdrs ),null );
    1016        }
    1017
    1018        /**
    1019         * 【TAG】ここに指定されたカラム列に NULL が現れた時点で読取を中止します。
    1020         *
    1021         * @og.tag
    1022         * これは、指定のカラムは必須という事を条件に、そのレコードだけを読み取る処理を行います。
    1023         * 複数Sheetの場合は、次のSheetを読みます。
    1024         * 現時点では、Excel の場合のみ有効です。
    1025         *
    1026         * @og.rev 5.5.8.2 (2012/11/09) 新規追加
    1027         *
    1028         * @param   clm カラム列
    1029         */
    1030        public void setNullBreakClm( final String clm ) {
    1031                nullBreakClm = nval( getRequestParameter( clm ),null );
    1032        }
    1033
    1034        /**
    1035         * 【TAG】ここに指定されたカラム列に NULL が現れたレコードは読み飛ばします。
    1036         *
    1037         * @og.tag
    1038         * 例えば、更新対象カラムで、null の場合は、何もしない、などのケースで使用できます。
    1039         * 複数カラムの場合は、AND条件やOR条件などが、考えられるため、
    1040         * カラムを一つにまとめて、指定してください。
    1041         *
    1042         * @og.rev 6.2.3.0 (2015/05/01) 行読み飛ばし nullSkipClm追加
    1043         *
    1044         * @param   clm カラム列
    1045         */
    1046        public void setNullSkipClm( final String clm ) {
    1047                nullSkipClm = nval( getRequestParameter( clm ),null );
    1048        }
    1049
    1050        /**
    1051         * 【TAG】読取元ファイルのカラム列を、外部(タグ)より指定します。
    1052         *
    1053         * @og.tag
    1054         * 読取元ファイルのカラム列を、外部(タグ)より指定します。
    1055         * ファイルに記述された #NAME より優先して使用されます。
    1056         * これは、元ファイルのカラムを順番に指定のカラム名に割り当てる機能で
    1057         * ファイルの特定のカラム列を抜き出して取り込む機能ではありません。
    1058         *
    1059         * ※ 7.2.6.0 (2020/06/30)
    1060         *      readerClass="POI"の場合、TEXT(テキスト)、CMNT(コメント)の位置は変えられません。
    1061         *      また、カラム数も、必ず、2以上必要です。
    1062         *      それより多い場合は、null値のカラムが作成されます。
    1063         *
    1064         * @og.rev 3.5.4.5 (2004/01/23) 新規作成
    1065         *
    1066         * @param   clms 読取元ファイルのカラム列 (CSV形式)
    1067         */
    1068        public void setColumns( final String clms ) {
    1069                columns = nval( getRequestParameter( clms ),columns );
    1070        }
    1071
    1072        /**
    1073         * 【TAG】読取対象外のカラム列を、外部(タグ)よりCSV形式で指定します。
    1074         *
    1075         * @og.tag
    1076         * 指定するカラム名に対して、読取処理を行いません。
    1077         * ここで指定するカラム名は、ファイルの #NAME または、columns で
    1078         * 指定するカラム名に対して、含まれている必要はありません。
    1079         * その場合は、ここでの指定は無視されます。
    1080         *
    1081         * @og.rev 6.1.0.0 (2014/12/26) omitNames 属性を追加
    1082         * @og.rev 6.2.2.0 (2015/03/27) ColumnAction インナークラスでパラメータを整理する。
    1083         *
    1084         * @param   clms 読取対象外のカラム列 (CSV形式)
    1085         */
    1086        public void setOmitNames( final String clms ) {
    1087                clmAct.omitNames = nval( getRequestParameter( clms ),null );
    1088        }
    1089
    1090        /**
    1091         * 読取対象外のカラム列を、追加指定します。
    1092         *
    1093         * 内部的な処理で、DirectTableInsertTag で、WRITABLE,ROWID などの
    1094         * データベースに存在しないカラムを、omit するための機能です。
    1095         * 属性定義してもよいのですが、統一的な処理方法が決まらないので、
    1096         * 取りあえず、暫定的に、サブクラスからのみ、して可能にしておきます。
    1097         * このメソッドは、setOmitNames( String ) が呼び出された後でしか
    1098         * 有効に機能しません。
    1099         *
    1100         * @og.rev 6.2.4.0 (2015/05/15) 無条件でOMITする名称を指定します。
    1101         *
    1102         * @param   omit 読取対象外の追加カラム列 (CSV形式)
    1103         */
    1104        protected void addOmitNames( final String omit ) {
    1105                if( clmAct.omitNames == null ) {
    1106                        clmAct.omitNames = omit;
    1107                }
    1108                else {
    1109                        clmAct.omitNames = "," + omit ;
    1110                }
    1111        }
    1112
    1113        /**
    1114         * 【TAG】読取元ファイルの整合性チェックを行うカラム列をカンマ指定します。
    1115         *
    1116         * @og.tag
    1117         * カラムオブジェクトのDBType属性に対応したチェックを行います。
    1118         * 指定のカラム名をCSV形式(CSV)で複数指定できます。
    1119         * 全てのカラムのチェックを行う場合は、"*" を指定して下さい。
    1120         * 分解方法は、通常のパラメータ取得後に、CSV分解します。
    1121         *
    1122         * @og.rev 3.6.0.2 (2004/10/04) 新規追加 取り込み時チェック用
    1123         * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSV分解に戻します。
    1124         * @og.rev 6.2.2.0 (2015/03/27) ColumnAction インナークラスでパラメータを整理する。
    1125         *
    1126         * @param   clms 整合性チェックを行うカラム列 (CSV形式)
    1127         */
    1128        public void setCheckColumns( final String clms ) {
    1129                clmAct.checkColumns = nval( getRequestParameter( clms ),null );
    1130        }
    1131
    1132        /**
    1133         * 【TAG】読取元ファイルのデータ変換を行うカラム列をカンマ指定します。
    1134         *
    1135         * @og.tag
    1136         * カラムオブジェクトのDBType属性に対応したデータ変換を行います。
    1137         * 指定のカラム名をCSV形式(CSV)で複数指定できます。
    1138         * 全てのカラムをデータ変換する場合は、"*" を指定して下さい。
    1139         * 分解方法は、通常のパラメータ取得後に、CSV分解します。
    1140         *
    1141         * @og.rev 3.6.0.2 (2004/10/04) 新規追加 取り込み時データ変換
    1142         * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSV分解に戻します。
    1143         * @og.rev 6.2.2.0 (2015/03/27) ColumnAction インナークラスでパラメータを整理する。
    1144         *
    1145         * @param   clms データ変換を行うカラム列 (CSV形式)
    1146         */
    1147        public void setAdjustColumns( final String clms ) {
    1148                clmAct.adjustColumns = nval( getRequestParameter( clms ),null );
    1149        }
    1150
    1151        /**
    1152         * 【TAG】NULL チェックすべきカラム列をCSV形式(CSV形式)で指定します。
    1153         *
    1154         * @og.tag nullCheck="AAA,BBB,CCC,DDD"
    1155         * 分解方法は、通常のパラメータ取得後に、CSV分解します。
    1156         *
    1157         * @og.rev 3.8.0.2 (2005/06/30) 新規追加
    1158         * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSV分解に戻します。
    1159         * @og.rev 6.2.2.0 (2015/03/27) ColumnAction インナークラスでパラメータを整理する。
    1160         *
    1161         * @param   clms カラム列(CSV形式)
    1162         */
    1163        public void setNullCheck( final String clms ) {
    1164                clmAct.nullCheck = nval( getRequestParameter( clms ),null );
    1165        }
    1166
    1167        /**
    1168         * 【TAG】行番号情報を、使用している/していない[true/false]を指定します(初期値:true)。
    1169         *
    1170         * @og.tag
    1171         * 通常のフォーマットでは、各行の先頭に行番号が出力されています。
    1172         * 読取時に、#NAME 属性を使用する場合は、この行番号を無視しています。
    1173         * #NAME 属性を使用せず、columns 属性でカラム名を指定する場合(他システムの
    1174         * 出力ファイルを読み取るケース等)では、行番号も存在しないケースがあり、
    1175         * その様な場合に、useNumber="false" を指定すれば、データの最初から読取始めます。
    1176         * この場合、出力データのカラムの並び順が変更された場合、columns 属性も
    1177         * 指定しなおす必要がありますので、できるだけ、#NAME 属性を使用するように
    1178         * してください。
    1179         * なお、EXCEL 入力には、この設定は適用されません。(暫定対応)
    1180         * 初期値は、true(使用する) です。
    1181         *
    1182         * @og.rev 3.7.0.5 (2005/04/11) 新規追加
    1183         *
    1184         * @param   useNo 行番号情報 [true:使用する/false:使用しない]
    1185         */
    1186        public void setUseNumber( final String useNo ) {
    1187                useNumber = nval( getRequestParameter( useNo ),useNumber );
    1188        }
    1189
    1190        /**
    1191         * 【TAG】読込件数が０件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する])。
    1192         *
    1193         * @og.tag
    1194         * 初期値は、false(続行する)です。
    1195         *
    1196         * @og.rev 4.3.7.0 (2009/06/01) 新規追加
    1197         *
    1198         * @param  cmd ０件時停止可否 [true:処理を中止する/false:続行する]
    1199         */
    1200        public void setStopZero( final String cmd ) {
    1201                stopZero = nval( getRequestParameter( cmd ), stopZero );
    1202        }
    1203
    1204        /**
    1205         * 【TAG】(通常は使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します(初期値:true)。
    1206         *
    1207         * @og.tag
    1208         * この値は、ファイルダウンロード処理に影響します。この値がtrueに指定された時にcommitされたDBTableModelが
    1209         * ファイルダウンロードの対象の表になります。
    1210         *
    1211         * このパラメーターは、通常、各タグにより実装され、ユーザーが指定する必要はありません。
    1212         * 但し、1つのJSP内でDBTableModelが複数生成される場合に、前に処理したDBTableModelについてファイルダウンロードをさせたい
    1213         * 場合は、後ろでDBTableModelを生成するタグで、明示的にこの値をfalseに指定することで、ファイルダウンロード処理の対象から
    1214         * 除外することができます。
    1215         *
    1216         * @og.rev 5.1.6.0 (2010/05/01) 新規作成
    1217         *
    1218         * @param  flag メイントランザクションかどうか [true:メイン/false:その他]
    1219         */
    1220        public void setMainTrans( final String flag ) {
    1221                isMainTrans = nval( getRequestParameter( flag ),isMainTrans );
    1222        }
    1223
    1224        /**
    1225         * 【TAG】(通常は使いません)データの読み飛ばし件数を設定します。
    1226         *
    1227         * @og.tag
    1228         * TAB区切りテキストやEXCEL等のデータの読み始めの初期値を指定します。
    1229         * ファイルの先頭行が、０行としてカウントしますので、設定値は、読み飛ばす
    1230         * 件数になります。(１と指定すると、１件読み飛ばし、２行目から読み込みます。)
    1231         * 読み飛ばしは、コメント行などは、無視しますので、実際の行数分読み飛ばします。
    1232         * ＃NAME属性や、columns 属性は、有効です。
    1233         *
    1234         * @og.rev 5.1.6.0 (2010/05/01) 新規作成
    1235         *
    1236         * @param       count 読み始めの初期値
    1237         */
    1238        public void setSkipRowCount( final String count ) {
    1239                skipRowCount = nval( getRequestParameter( count ),skipRowCount );
    1240        }
    1241
    1242        /**
    1243         * 【TAG】読取処理でKEY:VAL形式のコードリソースから、KEYを取り出す処理を行うかどうかを指定します
    1244         *              (初期値:USE_TABLE_READER_RENDERER[={@og.value SystemData#USE_TABLE_READER_RENDERER}])。
    1245         *
    1246         * @og.tag
    1247         * TableWriter_Renderer 系のクラスで出力した場合は、コードリソースがラベルで出力されます。
    1248         * そのファイルを読み取ると、当然、エラーになります。
    1249         * ここでは、コードリソースのカラムに対して、ラベルからコードを求める逆変換を行うことで、
    1250         * Renderer 系で出力したファイルを取り込むことができるようにします。
    1251         *
    1252         * ここでは、TableWriter 系と同様に、TableReader_Renderer 系のクラスを作るのではなく、
    1253         * 属性値のフラグで、制御します。
    1254         * 将来的には、TableWriter 系も廃止して、同様のフラグで制御するように変更する予定です。
    1255         * (初期値:システム定数のUSE_TABLE_READER_RENDERER[={@og.value SystemData#USE_TABLE_READER_RENDERER}])。
    1256         *
    1257         * @og.rev 5.2.1.0 (2010/10/01) 新規作成
    1258         * @og.rev 6.2.2.0 (2015/03/27) ColumnAction インナークラスでパラメータを整理する。
    1259         *
    1260         * @param  flag ラベル逆変換を行うかどうか [true:行う/false:行わない]
    1261         * @see         org.opengion.hayabusa.common.SystemData#USE_TABLE_READER_RENDERER
    1262         */
    1263        public void setUseRenderer( final String flag ) {
    1264                clmAct.useRenderer = nval( getRequestParameter( flag ),HybsSystem.sysBool( "USE_TABLE_READER_RENDERER" ) );
    1265        }
    1266
    1267        /**
    1268         * 【TAG】matchKeysをCSV形式で指定します。
    1269         *
    1270         * @og.tag
    1271         * ファイルから特定の行のみを読み取るためのmatchKeysを指定します。
    1272         * matchKeysで指定したカラムに対して、matchValsの正規表現でチェックします。
    1273         * 何も指定しない場合は、読取対象になります。
    1274         * matchVals と個数を合わせてください。
    1275         *
    1276         * @og.rev 6.4.6.0 (2016/05/27) 新規追加
    1277         *
    1278         * @param   keys カラム列(CSV形式文字)
    1279         * @see         #setMatchVals( String )
    1280         */
    1281        public void setMatchKeys( final String keys ) {
    1282                clmAct.matchKeys = getCSVParameter( keys );
    1283        }
    1284
    1285        /**
    1286         * 【TAG】matchValsをCSV形式で指定します。
    1287         *
    1288         * @og.tag
    1289         * ファイルから特定の行のみを読み取るためのmatchValsを指定します。
    1290         * matchKeysで指定したカラムに対して、matchValsの正規表現でチェックします。
    1291         * この機能はTableReader_Defaultのみ有効です。
    1292         * 何も指定しない場合は、読取対象になります。
    1293         * matchKeys と個数を合わせてください。
    1294         *
    1295         * @og.rev 6.4.6.0 (2016/05/27) 新規追加
    1296         *
    1297         * @param   vals カラム列に対する正規表現(CSV形式文字)
    1298         * @see         #setMatchKeys( String )
    1299         */
    1300        public void setMatchVals( final String vals ) {
    1301                clmAct.matchVals = getCSVParameter( vals );
    1302        }
    1303
    1304        /**
    1305         * 【TAG】ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)。
    1306         *
    1307         * @og.tag
    1308         * 通常のｴﾗｰﾒｯｾｰｼﾞは、ﾗﾍﾞﾙ（長）が使われますが、これをﾗﾍﾞﾙ（短）を使いたい場合に、true にセットします。
    1309         * ここでのラベル（短）は、ﾀｸﾞ修飾なしの、ﾗﾍﾞﾙ（短）です。
    1310         * 標準はfalse:利用しない=ﾗﾍﾞﾙ（長）です。
    1311         * true/false以外を指定した場合はfalse扱いとします。
    1312         *
    1313         * ﾗﾍﾞﾙﾘｿｰｽの概要説明があれば表示しますが、useSLabel="true" 時は、概要説明を表示しません。
    1314         *
    1315         * @og.rev 7.0.7.0 (2019/12/13) 新規追加
    1316         *
    1317         * @param prm SLABEL利用 [true:利用する/false:利用しない]
    1318         */
    1319        public void setUseSLabel( final String prm ) {
    1320                useSLabel = nval( getRequestParameter( prm ),useSLabel );
    1321        }
    1322
    1323        /**
    1324         * カラム処理を行う、内部クラス
    1325         *
    1326         * カラム個別に行う処理をまとめたクラスです。
    1327         * omitNames        ： 読取対象外のカラム列を、外部(タグ)よりCSV形式で指定します
    1328         * adjustColumns    ： 読取元ファイルのデータ変換を行うカラム列をカンマ指定します
    1329         * checkColumns     ： 読取元ファイルの整合性チェックを行うカラム列をカンマ指定します
    1330         * nullCheck        ： NULL チェックすべきカラム列をCSV形式(CSV形式)で指定します
    1331         *
    1332         * 名前配列設定で対象のカラムをピックアップし、値設定処理で、個々に処理します。
    1333         *
    1334         * @og.rev 6.2.2.0 (2015/03/27) ColumnAction 新規作成
    1335         */
    1336        protected static final class ColumnAction {
    1337                private String  omitNames               ;               // 読取対象外のカラム列を、外部(タグ)よりCSV形式で指定します
    1338                private String  adjustColumns   ;               // 読取元ファイルのデータ変換を行うカラム列をカンマ指定します
    1339                private String  checkColumns    ;               // 読取元ファイルの整合性チェックを行うカラム列をカンマ指定します
    1340                private String  nullCheck               ;               // NULL チェックすべきカラム列をCSV形式(CSV形式)で指定します
    1341                private int             errRowCount             = ERROR_ROW_COUNT;              // NULL チェックすべきカラム列をCSV形式(CSV形式)で指定します
    1342                private boolean useRenderer             ;               // 読取処理でKEY:VAL形式のコードリソースから、KEYを取り出す処理を行うかどうかを指定
    1343                private boolean isDebug                 ;               // debug ﾌﾗｸﾞ
    1344                private ErrorMessage errMsgObj  ;               // 6.2.5.0 (2015/06/05) 初期化します。
    1345
    1346                private int[]           clmNos          ;               // 新名前配列に対応した、値配列のアドレス
    1347                private int[]           actFlg          ;               // カラム処理の実行有無のフラグ管理
    1348                private String[]        mtVals          ;               // 6.4.6.0 (2016/05/27) 新名前配列に対応した、判定処理用のデータ(正規表現)
    1349
    1350                private String[]        matchKeys       ;               // 6.4.6.0 (2016/05/27) レコードの読取条件指定時のカラム列を配列で指定します
    1351                private String[]        matchVals       ;               // 6.4.6.0 (2016/05/27) レコードの読取条件指定時のカラム列に対応する正規表現データを配列で指定します
    1352
    1353                private static final int OMIT    = -1;          // OMIT だけ別。clmNosで、OMITフラグは除外する。
    1354                private static final int ADJUST  = 1;           // adjustColumns 処理フラグ
    1355                private static final int CHECK   = 2;           // checkColumns 処理フラグ
    1356                private static final int NULL_CH = 4;           // nullCheck  処理フラグ
    1357                private static final int MAT_KYS = 8;           // 6.4.6.0 (2016/05/27) matchKeys  処理フラグ
    1358
    1359                /**
    1360                 * 名前配列が設定された場合に、対象カラムのピックアップを行います。
    1361                 * このクラスでは、名前の再設定で、初期化されます。
    1362                 *
    1363                 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction 新規作成
    1364                 * @og.rev 6.2.5.0 (2015/06/05) ErrorMessage を、初期化します。
    1365                 * @og.rev 6.4.6.0 (2016/05/27) レコードの読取条件指定を追加
    1366                 *
    1367                 * @param       orgNms オリジナル名前配列
    1368                 * @return      OMIT等考慮した、新名前配列
    1369                 */
    1370                public String[] makeNames( final String[] orgNms ) {
    1371                        errMsgObj = new ErrorMessage( "Check Columns Error!" );         // 6.2.5.0 (2015/06/05) 初期化します。
    1372
    1373                        // omit だけ、他のフラグセットと異なり、処理された数は、除外されるので逆になります。
    1374                        final int[] temp = new int[orgNms.length];
    1375                        final int size = orgNms.length - actionFlagSet( omitNames, orgNms, OMIT, temp );
    1376
    1377                        if( size == 0 ) {       // 有りえないが、omitNames="*" を誤って指定した場合にはありうる。
    1378                                final String errMsg = "カラムがありません。omitNames=[" + omitNames + "]";
    1379                                throw new HybsSystemException( errMsg );
    1380                        }
    1381
    1382                        final String[] names = new String[size];
    1383                        clmNos = new int[size];
    1384                        int no = 0;
    1385                        for( int i=0; i<temp.length; i++ ) {
    1386                                if( temp[i] != OMIT ) {                         // 除外しない場合
    1387                                        names[no] = orgNms[i];                  // 名前配列に、オリジナルの名前をセット
    1388                                        clmNos[no]= i;                                  // カラムアドレスをセット(TableModelのカラム番号になる)
    1389                                        no++ ;
    1390                                }
    1391                        }
    1392
    1393                        actFlg = new int[size];                                 // 新名前配列に対応した、処理フラグを作成(フラグを加算)
    1394                        actionFlagSet( adjustColumns, names, ADJUST,  actFlg );         // それぞれのフラグが加算される。
    1395                        actionFlagSet( checkColumns,  names, CHECK,   actFlg );
    1396                        actionFlagSet( nullCheck,     names, NULL_CH, actFlg );
    1397
    1398                        // 6.4.6.0 (2016/05/27) レコードの読取条件指定を追加。ほとんど使わない機能。
    1399                        if( matchKeys != null && matchKeys.length > 0 ) {
    1400                                final Map<String,String> keyMap = makeMatchMap( matchKeys , matchVals );
    1401                                mtVals = new String[size];
    1402                                for( int i=0; i<size; i++ ) {
    1403                                        mtVals[i] = keyMap.get( names[i] );
    1404                                        if( mtVals[i] != null ) { actFlg[i] += MAT_KYS; }               // 一致するカラムにフラグを加算する。
    1405                                }
    1406                        }
    1407
    1408                        return names;
    1409                }
    1410
    1411                /**
    1412                 * 値配列に対して、変換処理、チェック処理を行った結果を返します。
    1413                 *
    1414                 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction 新規作成
    1415                 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    1416                 * @og.rev 6.4.1.2 (2016/01/22) HybsOverflowException をthrow するとき、最大件数を引数に渡す。
    1417                 * @og.rev 6.4.6.0 (2016/05/27) レコードの読取条件指定を追加
    1418                 * @og.rev 7.2.9.4 (2020/11/20) spotbugs:null になっている可能性があるメソッドの戻り値を利用している
    1419                 *
    1420                 * @param       vals    値配列
    1421                 * @param       dbClms  カラムオブジェクト配列
    1422                 * @param       row             行番号(エラーメッセージの表示用)
    1423                 * @return      変換、チェック処理結果の値配列。このレコードを使用しない場合は、null を返します。
    1424                 */
    1425                public String[] clmAction( final String[] vals , final DBColumn[] dbClms , final int row ) {
    1426                        // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    1427                        if( clmNos == null || actFlg == null ) {
    1428                                final String errMsg = "#makeNames(String[])を先に実行しておいてください。" ;
    1429                                throw new OgRuntimeException( errMsg );
    1430                        }
    1431
    1432//                      if( mtVals == null ) { return null; }                                                           // 7.2.9.4 (2020/11/20)
    1433
    1434                        final String[] rtnVals = new String[clmNos.length] ;
    1435                        boolean isError = false;
    1436
    1437                        for( int no=0; no<clmNos.length; no++ ) {
    1438                                String val = vals[clmNos[no]];
    1439                                if( useRenderer ) {                                                                                             // useRenderer(KEY:VAL) 処理
    1440                                        val = dbClms[no].getReaderValue( val );
    1441                                }
    1442                                if( (actFlg[no] & ADJUST) == ADJUST ) {                                                 // adjustColumns 処理
    1443                                        val = dbClms[no].valueSet( val );
    1444                                }
    1445                                if( (actFlg[no] & CHECK)  == CHECK  ) {                                                 // checkColumns 処理
    1446                                        final ErrorMessage msg = dbClms[no].valueCheck( val );
    1447                                        if( msg.getKekka() > ErrorMessage.OK ) {
    1448                                                isError = true;
    1449                                                errMsgObj.append( row+1,msg );
    1450                                        }
    1451                                }
    1452                                if( (actFlg[no] & NULL_CH) == NULL_CH ) {                                               // nullCheck 処理
    1453                                        if( val == null || val.isEmpty() ) {
    1454                                                isError = true;
    1455                                                // ERR0012 : 指定のデータがセットされていません。(NULLエラー)。key={0}
    1456                                                errMsgObj.addMessage( row+1,ErrorMessage.NG,"ERR0012",dbClms[no].getLabel() );
    1457                                        }
    1458                                }
    1459                                // 6.4.6.0 (2016/05/27) レコードの読取条件指定を追加
    1460                                // 6.9.7.0 (2018/05/14) PMD These nested if statements could be combined
    1461//                              if( (actFlg[no] & MAT_KYS) == MAT_KYS ) {                                               // 読取条件指定
    1462//                                      // このフラグが立っているということは、mtVals も、その値も、null ではない。
    1463//                                      if( !val.matches( mtVals[no] ) ) { return null; }                       // マッチしない場合は、null を返します。
    1464//                              }
    1465                                // 6.9.8.0 (2018/05/28) FindBugs:コンストラクタで初期化されていないフィールドを null チェックなしで null 値を利用している
    1466                                // このフラグが立っているということは、mtVals も、その値も、null ではない。
    1467                                if( (actFlg[no] & MAT_KYS) == MAT_KYS && !val.matches( mtVals[no] ) ) { return null; }  // マッチしない場合は、null を返します。
    1468
    1469                                rtnVals[no] = val;
    1470                        }
    1471
    1472                        // 5.5.7.2 (2012/10/09) エラー時のデバッグ出力
    1473                        if( isDebug && isError ) {
    1474                                errMsgObj.addMessage( row+1,ErrorMessage.NG,"Debug",vals );
    1475                        }
    1476
    1477                        // isDebug == true 時には、件数は倍になるが、仕方がない。
    1478                        if( errMsgObj.size() > errRowCount ) { throw new HybsOverflowException( errRowCount ); }                // 6.4.1.1 (2016/01/16)
    1479
    1480                        // adjustColumns 処理結果を反映させます。
    1481                        return rtnVals;
    1482                }
    1483
    1484                /**
    1485                 * ErrorMessageオブジェクトを返します。
    1486                 *
    1487                 * @og.rev 6.2.5.0 (2015/06/05) 新規作成
    1488                 *
    1489                 * @return      ErrorMessageオブジェクト
    1490                 */
    1491                public ErrorMessage getErrorMessage() {
    1492                        return errMsgObj ;
    1493                }
    1494
    1495                /**
    1496                 * 処理実行可否を判断し、フラグをセットします。
    1497                 *
    1498                 * フラグのセットは、"|"(論理和)するのが良いのですが、OMITもここで判定している関係で、
    1499                 * 単なる加算にしています。
    1500                 * (マイナスをフラグにしているので、マイナスの論理和が良く判らないためです(^^))
    1501                 *
    1502                 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction 新規作成
    1503                 *
    1504                 * @param       clms    指定のカラム名 (CSV形式)
    1505                 * @param       names   名前配列
    1506                 * @param       flag    設定するフラグ(既存の配列に加算)
    1507                 * @param       actFlg  オリジナル名前配列
    1508                 * @return      処理を行った件数
    1509                 */
    1510                private int actionFlagSet( final String clms , final String[] names , final int flag , final int[] actFlg ) {
    1511                        int cnt = 0;
    1512                        if( clms != null ) {
    1513                                final String clmStr = ',' + clms.replaceAll( " ","" ) + ',' ;           // 前後に カンマ(',') を追加、中間スペース削除
    1514                                for( int i=0; i<names.length; i++ ) {
    1515                                        // "*" はループの外で判定して、２回それぞれでループを回す方が早い・・・かな？
    1516                                        if( "*".equals( clms ) || clmStr.indexOf( ',' + names[i] + ',' ) >= 0 ) {
    1517                                                cnt++ ;
    1518                                                actFlg[i] += flag;                      // 一致するカラムにフラグを加算する。
    1519                                        }
    1520                                }
    1521                        }
    1522                        return cnt ;
    1523                }
    1524
    1525                /**
    1526                 * コードの読取条件指定のキーと値を関連付けるMapを作成します。
    1527                 *
    1528                 * ほとんど使用しない処理なので、できるだけ本体処理の影響が無いように、
    1529                 * メソッドを分けています。
    1530                 * このメソッドは、keys の、nullチェックを行ったうえで呼び出しています。
    1531                 * key,vals の個数が異なる場合は、エラーにしています。
    1532                 *
    1533                 * @og.rev 6.4.6.0 (2016/05/27) 新規作成
    1534                 *
    1535                 * @param       keys    指定のカラム名配列(呼び出し前に、nullでないことを確認済み)
    1536                 * @param       vals    指定の値配列
    1537                 * @return      カラム名と値のMap
    1538                 * @og.rtnNotNull
    1539                 */
    1540                private Map<String,String> makeMatchMap( final String[] keys , final String[] vals ) {
    1541
    1542                        // 6.4.6.0 (2016/05/27) レコードの読取条件指定を追加。個数判定
    1543                        if( vals != null && keys.length != vals.length ) {
    1544                                final String errMsg = "keys属性とvals属性の個数が合いません。"                                                  + CR
    1545                                                                        + " keys=[" + keys.length + "]:KEYS=" + StringUtil.array2csv( keys ) + CR
    1546                                                                        + " vals=[" + vals.length + "]:VLAS=" + StringUtil.array2csv( vals ) + CR ;
    1547                                throw new HybsSystemException( errMsg );
    1548                        }
    1549
    1550                        final Map<String,String> keyMap = new HashMap<>();              // 6.4.9.1 (2016/08/05)
    1551                        for( int i=0; i<keys.length; i++ ) {
    1552                                keyMap.put( keys[i] , vals[i] );
    1553                        }
    1554
    1555                        return keyMap;
    1556                }
    1557        }
    1558
    1559        /**
    1560         * AutoReader用の 簡易パラメータ管理用の内部クラスです。
    1561         *
    1562         * ３つのパラメータ(クラス、エンコード、サフィックス)を管理します。
    1563         *
    1564         * CLASS        TableReader_**** クラス の ****部分を指定します。(Excel,Calc,Text,PIO など)
    1565         * ENCODE       クラスが、Text の場合のエンコード(UnicodeLittle,Windows-31J,UTF-8,EUC-JP など)
    1566         * SUFIX        処理対象の拡張子(xls,xlsx,xlsm,ods など)
    1567         *
    1568         * @og.rev 6.2.5.0 (2015/06/05) 新規追加。AutoReader用の 簡易パラメータ管理用の内部クラス
    1569         */
    1570        private static final class AutoReaderParam {
    1571                public final String CLASS       ;
    1572                public final String ENCODE      ;
    1573                public final String SUFIX       ;
    1574
    1575                /**
    1576                 * AutoReader用の 簡易パラメータ管理用の内部クラスのコンストラクターです。
    1577                 *
    1578                 * ３つのパラメータ(クラス、エンコード、サフィックス)を管理します。
    1579                 *
    1580                 * @og.rev 6.2.5.0 (2015/06/05) 新規追加。AutoReader用の 簡易パラメータ管理用の内部クラス
    1581                 *
    1582                 * @param       cls     TableReader_**** クラス の ****部分を指定します。(Excel,Calc,Text,PIO など)
    1583                 * @param       enc     クラスが、Text の場合のエンコード(UnicodeLittle,Windows-31J,UTF-8,EUC-JP など)
    1584                 * @param       sfx     処理対象の拡張子(xls,xlsx,xlsm,ods など) nullの場合は、すべてを対象とする。
    1585                 */
    1586                public AutoReaderParam( final String cls , final String enc , final String sfx ) {
    1587                        CLASS   = cls ;
    1588                        ENCODE  = enc ;
    1589                        SUFIX   = sfx == null ? null : ',' + sfx + ',' ;                // 判定用なので、
    1590                }
    1591
    1592                /**
    1593                 * 引数のサフィックスが、対象かどうか、判定します。
    1594                 * 対象の場合は、true 、対象でない場合は、false を返します。
    1595                 *
    1596                 * @og.rev 6.2.5.0 (2015/06/05) 新規追加。AutoReader用の 簡易パラメータ管理用の内部クラス
    1597                 *
    1598                 * @param       sufix   比較対象の拡張子(小文字のみ判定可能)
    1599                 * @return      対象かどうか[true:対象/false:対象外]
    1600                 */
    1601                public boolean useSufix( final String sufix ) {
    1602                        return SUFIX == null || SUFIX.contains( ',' + sufix + ',' ) ;
    1603                }
    1604
    1605                /**
    1606                 * オブジェクトの文字列表現を返します。
    1607                 * 対象の場合は、true 、対象でない場合は、false を返します。
    1608                 *
    1609                 * @og.rev 6.2.5.0 (2015/06/05) 新規追加。AutoReader用の 簡易パラメータ管理用の内部クラス
    1610                 *
    1611                 * @return      このオブジェクトの文字列表現
    1612                 */
    1613                @Override
    1614                public String toString() {
    1615                        return "class=[" + CLASS + "] , encode=[" + ENCODE + "] , sufix=[" + SUFIX + "]" ;
    1616                }
    1617        }
    1618
    1619        /**
    1620         * このオブジェクトの文字列表現を返します。
    1621         * 基本的にデバッグ目的に使用します。
    1622         *
    1623         * @return このクラスの文字列表現
    1624         * @og.rtnNotNull
    1625         */
    1626        @Override
    1627        public String toString() {
    1628                return ToString.title( this.getClass().getName() )
    1629                                .println( "VERSION"                     ,VERSION        )
    1630                                .println( "separator"           ,separator              )
    1631                                .println( "fileURL"             ,fileURL                )
    1632                                .println( "filename"            ,filename               )
    1633                                .println( "encode"                      ,encode                 )
    1634                                .println( "readerClass"         ,readerClass    )
    1635                                .println( "maxRowCount"         ,maxRowCount    )
    1636                                .println( "displayMsg"          ,displayMsg             )
    1637                                .println( "executeCount"        ,executeCount   )
    1638                                .println( "modifyType"          ,modifyType             )
    1639                                .println( "command"                     ,command                )
    1640                                .println( "tableId"                     ,tableId                )
    1641                                .println( "sheetName"           ,sheetName              )
    1642                                .println( "sheetNos"            ,sheetNos               )               // 5.5.7.2 (2012/10/09)
    1643                                .println( "columns"                     ,columns                )
    1644                                .println( "useNumber"           ,useNumber              )
    1645                                .println( "Other..."    ,getAttributes().getAttribute() )
    1646                                .fixForm().toString() ;
    1647        }
    1648}