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