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 static org.opengion.fukurou.util.StringUtil.*; 019 020import java.io.BufferedReader; 021import java.io.File; 022import java.io.IOException; 023import java.io.InputStream; 024import java.io.InputStreamReader; 025import java.io.ObjectInputStream; 026import java.io.ObjectOutputStream; 027import java.io.UnsupportedEncodingException; 028import java.nio.file.Files; 029import java.util.Locale ; 030 031import javax.servlet.http.HttpServletRequest; 032import javax.servlet.http.HttpSession; 033 034import org.opengion.fukurou.util.Closer ; 035import org.opengion.fukurou.util.ErrorMessage; 036import org.opengion.fukurou.util.FileUtil; 037import org.opengion.fukurou.util.StringUtil ; 038import org.opengion.hayabusa.common.HybsSystem; 039import org.opengion.hayabusa.common.HybsSystemException; 040import org.opengion.hayabusa.db.DBColumn; 041import org.opengion.hayabusa.db.DBTableModel; 042import org.opengion.hayabusa.io.StorageAPI; 043import org.opengion.hayabusa.io.StorageAPIFactory; 044import org.opengion.hayabusa.io.TableReader; 045 046/** 047 * 指定のファイルを DBTableModelオブジェクトに読み取るファイル入力タグです。 048 * 049 * データ(DBTableModel)と、コントローラ(ReadTableタグ)を与えて、外部からコントロールすることで、 050 * 各種形式で データ(DBTableModel)を表示させることが できます。 051 * ReadTableタグ に対して、コマンドを与えることにより、内部のコントローラの実装に対応した 052 * 形式でデータを作成します。 053 * すべての読取の初期クラス名を リソースファイルの TABLE_READER_DEFAULT_CLASS で指定可能です。 054 * その場合、AutoReader を指定すると、Excel と Default(テキスト) を順番に試します。 055 * 056 * 入力件数を"DB.COUNT" キーでリクエストにセットしています。 057 * 058 * @og.formSample 059 * ●形式: 060 * <og:readTable 061 * command = "NEW" 062 * fileURL = "{@USER.ID}" 読み取り元ディレクトリ名 063 * filename = "{@filename}" 読み取り元ファイル名 064 * encode = "UnicodeLittle" 読み取り元ファイルエンコード名 065 * maxRowCount = "10000" 読取最大件数(0:[無制限]) 066 * /> 067 * ●body:なし 068 * 069 * ●Tag定義: 070 * <og:readTable 071 * readerClass 【TAG】実際に読み出すクラス名の略称(TableReader_**** の ****)をセットします({@og.doc03Link readerClass 初期値:Default}) 072 * fileURL 【TAG】読み取り元ディレクトリ名を指定します(初期値:FILE_URL) 073 * filename 【TAG】ファイルを作成するときのファイル名をセットします (初期値:FILE_FILENAME[=file.xls]) 074 * encode 【TAG】ファイルを作成するときのファイルエンコーディング名をセットします(初期値:FILE_ENCODE) 075 * maxRowCount 【TAG】読取時の最大取り込み件数をセットします (初期値:DB_MAX_ROW_COUNT[=1000])(0:[無制限]) 076 * separator 【TAG】可変長ファイルを作成するときの項目区切り文字をセットします 077 * tableId 【TAG】(通常使いません)sessionから所得する DBTableModelオブジェクトの ID 078 * command 【TAG】コマンド(NEW,RENEW)をセットします(初期値:NEW) 079 * modifyType 【TAG】ファイル取り込み時の モディファイタイプ(A(追加),C(更新),D(削除))を指定します 080 * displayMsg 【TAG】query の結果を画面上に表示するメッセージIDを指定します(初期値:MSG0033[ 件検索しました]) 081 * notfoundMsg 【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした]) 082 * sheetName 【TAG】EXCELファイルを読み込むときのシート名を設定します(初期値:指定なし) 083 * sheetNos 【TAG】EXCELファイルを読み込むときのシート番号を複数設定できます(初期値:0) 084 * sheetConstKeys 【TAG】EXCELファイルを読み込むときの固定値となるカラム名(CSV形式) 085 * sheetConstAdrs 【TAG】EXCELファイルを読み込むときの固定値となるアドレス(行-列,行-列,・・・) 086 * nullBreakClm 【TAG】カラム列に NULL が現れた時点で読み取りを中止します(複数Sheetの場合は、次のSheetを読みます)。 087 * columns 【TAG】読み取り元ファイルのカラム列を、外部(タグ)より指定します 088 * useNumber 【TAG】行番号情報を、使用している/していない[true/false]を指定します(初期値:true) 089 * adjustColumns 【TAG】読み取り元ファイルのデータ変換を行うカラム列をカンマ指定します 090 * checkColumns 【TAG】読み取り元ファイルの整合性チェックを行うカラム列をカンマ指定します 091 * nullCheck 【TAG】NULL チェックすべきカラム列をカンマ区切り(CVS形式)で指定します 092 * language 【TAG】タグ内部で使用する言語コード[ja/en/zh/…]を指定します 093 * stopZero 【TAG】読込件数が0件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する]) 094 * scope 【TAG】キャッシュする場合のスコープ[request/page/session/applicaton]を指定します(初期値:session) 095 * mainTrans 【TAG】(通常使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します(初期値:false) 096 * skipRowCount 【TAG】(通常は使いません)データの読み飛ばし件数を設定します 097 * useRenderer 【TAG】読取処理でラベルをコードリソースに逆変換を行うかどうかを指定します (初期値:USE_TABLE_READER_RENDERER[=false]) 098 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 5.7.7.2 (2014/06/20) 099 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 5.7.7.2 (2014/06/20) 100 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:true) 5.7.7.2 (2014/06/20) 101 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:true) 5.7.7.2 (2014/06/20) 102 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 103 * /> 104 * 105 * ●使用例 106 * 107 * <og:readTable 108 * command = "NEW" 109 * readerClass = "Fixed" 固定長データの読み取り 110 * modifyType = "{@modifyType}" 読取時のモディファイタイプ(A,C等) 111 * fileURL = "{@USER.ID}" 読み取り元ディレクトリ名 112 * filename = "{@filename}" 読み取り元ファイル名 113 * encode = "Shift_JIS" 読み取り元ファイルエンコード名 114 * maxRowCount = "10000" 読取最大件数(0:[無制限]) 115 * columns = "OYA,KO,HJO,SU,DYSTR,DYEND" #NAME に対応するカラム列 116 * useNumber = "false" 行番号の存在しないデータを読み取ります。 117 * adjustColumns = "OYA,KO,HJO,SU" データ変換するカラム列("*" で全カラム) 118 * checkColumns = "OYA,KO,HJO,SU" 整合性チェックするカラム列("*" で全カラム) 119 * nullCheck = "OYA,KO,SU" NULLチェックを実行します("*" で全カラム) 120 * stopZero = "true" 取得0件の場合に以降の処理を停止します 121 * skipRowCount = "4" データの読み飛ばし件数(読み込み開始は、この数字+1行目から) 122 * /> 123 * 124 * @og.group ファイル入力 125 * 126 * @version 4.0 127 * @author Kazuhiko Hasegawa 128 * @since JDK5.0, 129 */ 130public class ReadTableTag extends CommonTagSupport { 131 //* このプログラムのVERSION文字列を設定します。 {@value} */ 132 private static final String VERSION = "5.7.7.2 (2014/06/20)" ; 133 134 private static final long serialVersionUID = 577220140620L ; 135 136 private static final int ERROR_ROW_COUNT = 200 ; // 4.0.0 (2007/05/25) 137 138 /** command 引数に渡す事の出来る コマンド 新規作成 {@value} */ 139 public static final String CMD_NEW = "NEW" ; 140 /** command 引数に渡す事の出来る コマンド 再検索 {@value} */ 141 public static final String CMD_RENEW = "RENEW" ; 142 143 private static final String[] COMMAND_LIST = new String[] { CMD_NEW , CMD_RENEW }; 144 145 // 5.9.25.2 (2017/10/27) 146 private final String CLOUD_STORAGE = HybsSystem.sys( "CLOUD_STORAGE"); 147 private final String CLOUD_CONTAINER = HybsSystem.sys("CLOUD_STORAGE_CONTAINER"); 148 149 150 private String separator = TableReader.TAB_SEPARATOR; // 項目区切り文字 151 private String fileURL = HybsSystem.sys( "FILE_URL" ); 152 private String filename = HybsSystem.sys( "FILE_FILENAME" ); // ファイル名 153 private String encode = HybsSystem.sys( "FILE_ENCODE" ); // ファイルエンコーディング "JISAutoDetect" ,"JIS", "EUC_JP", "MS932", "SJIS" , "Windows-31J" , "Shift_JIS" 154 private String readerClass = HybsSystem.sys( "TABLE_READER_DEFAULT_CLASS" ); // 3.8.5.3 (2006/08/07) 155 private int maxRowCount = -1; 156 private String displayMsg = HybsSystem.sys( "VIEW_DISPLAY_MSG" ); 157 private String notfoundMsg = "MSG0077"; // 対象データはありませんでした。 158 private int executeCount = -1; // 検索/実行件数 159 private String modifyType = null; 160 private String adjustColumns = null; // 3.6.0.2 (2004/10/04) 取り込み時チェック 161 private String checkColumns = null; // 3.6.0.2 (2004/10/04) 取り込み時チェック 162 private String nullCheck = null; // 3.8.0.2 (2005/06/30) nullチェック確認 163 164 private transient DBTableModel table = null; 165 private String command = CMD_NEW; 166 private String tableId = HybsSystem.TBL_MDL_KEY ; 167 private String sheetName = null ; // 3.5.4.2 (2003/12/15) 168 private String sheetNos = null ; // 5.5.7.2 (2012/10/09) 複数シートを指定できるようにシート番号を指定できるようにする。 169 private String sheetConstKeys = null ; // 5.5.8.2 (2012/11/09) 固定値となるカラム名(CSV形式) 170 private String sheetConstAdrs = null ; // 5.5.8.2 (2012/11/09) 固定値となるアドレス(行-列,行-列,・・・) 171 private String nullBreakClm = null; // 5.5.8.2 (2012/11/09) 取込み条件/Sheet BREAK条件 172 173 // 3.5.4.5 (2004/01/23) 外部よりカラム列(カンマ区切り)を指定できるようにする。 174 private String columns = null; 175 private boolean useNumber = true; // 3.7.0.5 (2005/04/11) 176 177 private boolean stopZero = false; // 4.3.7.0 (2009/06/01) stopZero属性追加 178 179 // 5.1.8.0 (2010/07/01) AutoReaderのCalc対応 180 private static final String[] AUTO_READER_CLASS = new String[] { "Excel","Calc","Default" ,"Default" }; 181 private static final String[] AUTO_READER_ENCODE = new String[] { null ,null ,"UnicodeLittle","Windows-31J" }; 182 183 private boolean isMainTrans = true; // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し 184 private int skipRowCount = 0; // 5.1.6.0 (2010/05/01) データの読み飛ばし設定 185 186 // 5.9.8.1 (2016/05/13) 追加 187 private String[] matchKeys = null; 188 private String[] matchVals = null; 189 190 // 5.2.1.0 (2010/10/01) 読取処理でコードリソースのラベル変換を行うかどうか 191 private boolean useRenderer = HybsSystem.sysBool( "USE_TABLE_READER_RENDERER" ); // 5.2.1.0 (2010/10/01) 192 193 /** 194 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 195 * 196 * @og.rev 3.0.1.4 (2003/03/17) displayMsg が 0Byteの場合は、件数も表示しないように変更。 197 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 198 * @og.rev 3.5.4.1 (2003/12/01) 引数の BufferedReader を、InputStream に変更。 199 * @og.rev 3.5.4.3 (2004/01/05) 引数の InputStream を、 BufferedReader に戻す。 200 * @og.rev 3.5.6.5 (2004/08/09) 暫定的に、DBTableModelを先行削除します。 201 * @og.rev 3.6.0.0 (2004/09/24) DBTableModel の先行削除は、scope="session" の場合のみ。 202 * @og.rev 3.6.0.2 (2004/10/04) 取り込み時チェック用に、checkColumns,adjustColumns 属性追加 203 * @og.rev 3.6.0.8 (2004/11/19) DBTableModel をセーブする時に、トランザクションチェックを行います。 204 * @og.rev 3.8.5.3 (2006/08/07) readerClassが "Excel"でエラーが発生したとき、もう一度Defaultで再読取を行います。 205 * @og.rev 4.0.0.0 (2007/10/12) checkTableColumn 前に、modifyType 設定を行います。 206 * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( getResource().getMessage ⇒ getResource().getLabel ) 207 * @og.rev 4.3.1.1 (2008/10/08) columnsが指定されている場合は、AutoReader禁止 208 * @og.rev 4.3.7.0 (2009/06/01) stopZero機能,DB.COUNTリクエストキーへ読込件数セットを追加 209 * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は、DBTableModelが新規作成された処理でのみ行う。 210 * @og.rev 5.1.8.0 (2010/07/01) AutoReaderのCalc対応 211 * @og.rev 5.1.9.0 (2010/08/01) AutoReaderでのExceptionの判定をThrowableに変更 212 * @og.rev 5.7.1.2 (2013/12/20) tempMsg.toString() ⇒ errMsg 変更 213 * @og.rev 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加 214 * 215 * @return 後続処理の指示 216 */ 217 @Override 218 public int doEndTag() { 219 debugPrint(); // 4.0.0 (2005/02/28) 220 // 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加 221 if( !useTag() ) { return EVAL_PAGE ; } 222 223 if( check( command, COMMAND_LIST ) ) { 224 useMainTrans( isMainTrans ); // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し 225 startQueryTransaction( tableId ); // 3.6.0.8 (2004/11/19) 226 227 // 3.5.6.5 (2004/08/09) 削除するのは、セッションのオブジェクトでよい。 228 // 3.6.0.0 (2004/09/24) 削除するのは、scope="session" の場合のみ。 229 if( "session".equals( getScope() ) ) { 230 removeSessionAttribute( tableId ); 231 removeSessionAttribute( HybsSystem.VIEWFORM_KEY ); 232 } 233 234 if( maxRowCount < 0 ) { 235 maxRowCount = sysInt( "DB_MAX_ROW_COUNT" ); 236 } 237 238 // ファイル の読み込み:AutoReader 処理 239 BufferedReader pw = null; 240 final String[] READER_CLASS ; 241 final String[] READER_ENCODE ; 242 if( "AutoReader".equalsIgnoreCase( readerClass ) ) { 243 // 4.3.1.1 (2008/10/08) 244 if( columns != null && columns.length() > 0 ) { 245 String errMsg = "columnsが指定されている場合は、readerClass=\"AutoReader\"は使えません"; 246 throw new HybsSystemException( errMsg ); // 4.3.4.4 (2009/01/01) 247 } 248 READER_CLASS = AUTO_READER_CLASS ; 249 READER_ENCODE = AUTO_READER_ENCODE; 250 } 251 else { 252 READER_CLASS = new String[] { readerClass }; 253 READER_ENCODE = new String[] { encode }; 254 } 255 256 StringBuilder tempMsg = new StringBuilder(); 257 for( int i=0; i<READER_CLASS.length; i++ ) { 258 readerClass = READER_CLASS[i]; 259 encode = READER_ENCODE[i]; 260 261 try { 262 // 5.1.8.0 (2010/07/01) AutoReaderのCalc対応 263 if( "Excel".equalsIgnoreCase( readerClass ) || "Calc".equalsIgnoreCase( readerClass ) ) { 264 create( null ); 265 } 266 else { 267 pw = getBufferedReader(); 268 create( pw ); 269 } 270 // 成功すれば、エラーメッセージをクリアして、その場で抜ける。 271 tempMsg = null; 272 break; 273 } 274 // 3.8.5.3 (2006/08/07) readerClassが "Excel"でエラーが発生したとき、もう一度Defaultで再読取を行います。 275 // 5.1.9.0 (2010/08/01) RuntimeException系のExceptionがキャッチできないため、Throwableで受ける 276 catch( Throwable th ) { 277 tempMsg.append( "readerClass=[" ).append( readerClass ) 278 .append( "],encode=[" ).append( encode ) 279 .append( "] Error!" ).append( HybsSystem.CR ) 280 .append( th.getMessage() ).append( HybsSystem.CR ) ; 281 } 282 finally { 283 Closer.ioClose( pw ); // 4.0.0 (2006/01/31) close 処理時の IOException を無視 284 } 285 } 286 287 if( tempMsg != null ) { // 最後までエラーがあれば、例外処理を発行します。 288 String errMsg = tempMsg.toString(); 289 System.err.print( errMsg ); 290 throw new HybsSystemException( errMsg ); // 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更 291 } 292 293 if( table != null ) { 294 // 3.6.0.2 (2004/10/04) 295 // 4.0.0.0 (2007/10/12) checkTableColumn 前に、modifyType 設定を行います。 296 executeCount = table.getRowCount(); 297 if( modifyType != null ) { 298 for( int row=0; row<executeCount; row++ ) { 299 table.setModifyType( row,modifyType ); 300 } 301 } 302 303 ErrorMessage errMsg = checkTableColumn( table ); 304 if( errMsg != null && ! errMsg.isOK()) { 305 jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg,getResource() ) ); 306 return SKIP_PAGE ; 307 } 308 309 } 310 // 3.6.0.8 (2004/11/19) トランザクションチェックを行います。 311 if( ! commitTableObject( tableId, table ) ) { 312 jspPrint( "ReadTableTag Query処理が割り込まれました。DBTableModel は登録しません。" ); 313 return SKIP_PAGE ; 314 } 315 316 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_SMALL ); 317 318 // 実行件数の表示 command="NEW" のときのみ、displayMsg を表示させます。 319 // 4.0.0 (2005/11/30) 出力順の変更。一番最初に出力します。 320 if( CMD_NEW.equals( command ) ) { 321 if( executeCount > 0 && displayMsg != null && displayMsg.length() > 0 ) { 322 buf.append( executeCount ); 323 buf.append( getResource().getLabel( displayMsg ) ); 324 buf.append( HybsSystem.BR ); 325 } 326 else if( executeCount == 0 && notfoundMsg != null && notfoundMsg.length() > 0 ) { 327 buf.append( getResource().getLabel( notfoundMsg ) ); 328 buf.append( HybsSystem.BR ); 329 } 330 } 331 332 // 4.3.7.0 (2009/06/01) 読込件数を、"DB.COUNT" キーでリクエストにセットする。 333 setRequestAttribute( "DB.COUNT" , String.valueOf( executeCount ) ); 334 335 jspPrint( buf.toString() ); 336 } 337 338 // 4.3.7.0 (2009/06/01) stopZero機能を追加 339 final int rtnCode ; 340 if( executeCount == 0 && stopZero ) { 341 rtnCode = SKIP_PAGE; 342 } 343 else { 344 rtnCode = EVAL_PAGE; 345 } 346 347 return rtnCode ; 348 } 349 350 /** 351 * タグリブオブジェクトをリリースします。 352 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 353 * 354 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加 355 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 356 * @og.rev 3.1.3.0 (2003/04/10) FILE_ENCODE から、エンコード情報を取得する。 357 * @og.rev 3.1.4.0 (2003/04/18) command 属性に、初期値(NEW)を設定する。 358 * @og.rev 3.5.4.2 (2003/12/15) EXCELのシート名を指定できるように変更。 359 * @og.rev 3.5.4.5 (2004/01/23) 外部よりカラム列(カンマ区切り)を指定できるようにする。 360 * @og.rev 3.6.0.2 (2004/10/04) checkColumns,adjustColumns,allColumnCheck 属性追加 361 * @og.rev 3.7.0.5 (2005/04/11) useNumber 属性を追加します。 362 * @og.rev 3.8.0.2 (2005/06/30) nullCheck 属性追加 363 * @og.rev 3.8.5.3 (2006/08/07) readerClass 属性の初期値をシステムリソースより取得します。 364 * @og.rev 4.3.7.0 (2009/06/01) stopZero属性追加 365 * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は、DBTableModelが新規作成された処理でのみ行う。 366 * @og.rev 5.1.6.0 (2010/05/01) データの読み飛ばし設定 skipRowCount 属性追加 367 * @og.rev 5.2.1.0 (2010/10/01) 読取処理でコードリソースのラベル変換を行うかどうか useRenderer 属性追加 368 * @og.rev 5.5.7.2 (2012/10/09) 複数シートを指定できるようにシート番号を指定できるように、sheetNos属性追加 369 * @og.rev 5.5.8.2 (2012/11/09) 固定値となるカラム名、アドレスの指定のための、sheetConstKeys、sheetConstAdrs属性追加 370 * @og.rev 5.5.8.2 (2012/11/09) カラム列に NULL が現れた時点で読み取りを中止する、nullBreakClm属性追加 371 * @og.rev 5.9.8.1 (2016/05/13) 読込条件の追加 372 */ 373 @Override 374 protected void release2() { 375 super.release2(); 376 separator = TableReader.TAB_SEPARATOR; // 項目区切り文字 377 fileURL = HybsSystem.sys( "FILE_URL" ); 378 filename = HybsSystem.sys( "FILE_FILENAME" ); // ファイル名 379 encode = HybsSystem.sys( "FILE_ENCODE" ); // ファイルエンコーディング "JISAutoDetect" ,"JIS", "EUC_JP", "MS932", "SJIS" , "Windows-31J" , "Shift_JIS" 380 readerClass = HybsSystem.sys( "TABLE_READER_DEFAULT_CLASS" ); // 3.8.5.3 (2006/08/07) 381 maxRowCount = -1; 382 displayMsg = HybsSystem.sys( "VIEW_DISPLAY_MSG" ); 383 notfoundMsg = "MSG0077"; // 対象データはありませんでした。 384 executeCount = -1; // 検索/実行件数 385 modifyType = null; 386 command = CMD_NEW; 387 table = null; 388 tableId = HybsSystem.TBL_MDL_KEY ; 389 sheetName = null; // 3.5.4.2 (2003/12/15) 390 sheetNos = null ; // 5.5.7.2 (2012/10/09) 複数シートを指定できるようにシート番号を指定できるようにする。 391 sheetConstKeys = null ; // 5.5.8.2 (2012/11/09) 固定値となるカラム名(CSV形式) 392 sheetConstAdrs = null ; // 5.5.8.2 (2012/11/09) 固定値となるアドレス(行-列,行-列,・・・) 393 nullBreakClm = null; // 5.5.8.2 (2012/11/09) 取込み条件/Sheet BREAK条件 394 columns = null; // 3.5.4.5 (2004/01/23) 395 useNumber = true; // 3.7.0.5 (2005/04/11) 396 adjustColumns = null; // 3.6.0.2 (2004/10/04) 取り込み時チェック 397 checkColumns = null; // 3.6.0.2 (2004/10/04) 取り込み時チェック 398 nullCheck = null; // 3.8.0.2 (2005/06/30) 399 stopZero = false; // 4.3.7.0 (2009/06/01) soptZero追加 400 isMainTrans = true; // 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し 401 skipRowCount = 0; // 5.1.6.0 (2010/05/01) データの読み飛ばし設定 402 matchKeys = null; // 5.9.8.1 (2016/05/13) 読込条件設定 403 matchVals = null; // 5.9.8.1 (2016/05/13) 読込条件設定 404 useRenderer = HybsSystem.sysBool( "USE_TABLE_READER_RENDERER" ); // 5.2.1.0 (2010/10/01) 405 } 406 407 /** 408 * TableReader の実オブジェクトを生成して,BufferedReader に書き込みます。 409 * 410 * @og.rev 3.5.4.1 (2003/12/01) 引数の BufferedReader を、InputStream に変更。 411 * @og.rev 3.5.4.2 (2003/12/15) TableReader のサブクラス名変更。 412 * @og.rev 3.5.4.2 (2003/12/15) EXCELのシート名を指定できるように変更。 413 * @og.rev 3.5.4.3 (2004/01/05) 引数の InputStream を、 BufferedReader に戻す。 414 * @og.rev 3.5.4.5 (2004/01/23) TableReader に、encode を渡すように変更。 415 * @og.rev 3.5.6.0 (2004/06/18) 各種プラグイン関連付け設定を、システムパラメータ に記述します。 416 * @og.rev 3.7.0.5 (2005/04/11) useNumber 属性を追加します。 417 * @og.rev 4.0.0.0 (2005/01/31) キーの指定を、TableReader. から、TableReader_ に変更します。 418 * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更 419 * @og.rev 5.1.6.0 (2010/05/01) データの読み飛ばし設定 skipRowCount 属性追加 420 * @og.rev 5.2.1.0 (2010/10/01) 読取処理でコードリソースのラベル変換を行うかどうか設定 useRenderer 属性追加 421 * @og.rev 5.5.7.2 (2012/10/09) 複数シートを指定できるようにシート番号を指定できるように、sheetNos属性追加 422 * @og.rev 5.5.8.2 (2012/11/09) 固定値となるカラム名、アドレスの指定のための、sheetConstKeys、sheetConstAdrs属性追加 423 * @og.rev 5.5.8.2 (2012/11/09) カラム列に NULL が現れた時点で読み取りを中止する、nullBreakClm属性追加 424 * @og.rev 5.9.8.1 (2016/05/13) match対応 425 * @og.rev 5.9.25.2 (2017/10/27) クラウドストレージ対応 426 * 427 * @param out 出力するBufferedReaderオブジェクト 428 */ 429 protected void create( final BufferedReader out ) { 430 String className = HybsSystem.sys( "TableReader_" + readerClass ) ; // 4.0.0 (2005/01/31) 431 TableReader reader = (TableReader)HybsSystem.newInstance( className ); // 3.5.5.3 (2004/04/09) 432 reader.setResourceManager( getResource() ); // 4.0.0 (2005/01/31) 433 reader.setSeparator( separator ); 434 reader.setEncode( encode ); // 3.5.4.5 (2004/01/23) 435 reader.setColumns( columns ); // 3.5.4.5 (2004/01/23) 436 reader.setUseNumber( useNumber ); // 3.7.0.5 (2005/04/11) 437 reader.setMaxRowCount( maxRowCount ); 438 reader.setSkipRowCount( skipRowCount ); // 5.1.6.0 (2010/05/01) 439 reader.setUseRenderer( useRenderer ); // 5.2.1.0 (2010/10/01) 440 reader.setMatchKeys( matchKeys ); // 5.9.8.1 (2016/05/13) 441 reader.setMatchVals( matchVals ); // 5.9.8.1 (2016/05/13) 442 reader.setDebug( isDebug() ); // 5.5.7.2 (2012/10/09) デバッグ情報を出力するかどうかを指定 443 if( reader.isExcel() ) { // 3.5.4.3 (2004/01/05) 444 // 5.9.25.2 (2017/10/27) 445 String filePath = ""; 446 try{ 447 if(CLOUD_STORAGE != null && CLOUD_STORAGE.length() > 0){ 448 // クラウド上のファイルをサーバにダウンロードする。 449 filePath = downloadStorageFile(CLOUD_STORAGE, CLOUD_CONTAINER); 450 } 451 452 reader.setFilename( HybsSystem.url2dir( StringUtil.urlAppend( fileURL,filename ))); 453 reader.setSheetName( sheetName ); // 3.5.4.2 (2003/12/15) 454 reader.setSheetNos( sheetNos ); // 5.5.7.2 (2012/10/09) 複数シートを指定できるようにシート番号を指定できるようにする。 455 reader.setSheetConstData( sheetConstKeys,sheetConstAdrs ) ; // 5.5.8.2 (2012/11/09) 固定値となるカラム名、アドレスの指定 456 reader.setNullBreakClm( nullBreakClm ) ; // 5.5.8.2 (2012/11/09) 取込み条件/Sheet BREAK条件 457 reader.readDBTable(); 458 459 // 5.9.25.2 (2017/10/27) 460 }finally{ 461 if(CLOUD_STORAGE != null && CLOUD_STORAGE.length() > 0){ 462 // サーバにダウンロードしたファイルを削除 463 File file = new File(filePath); 464 if(file.exists()){ 465 file.delete(); 466 } 467 } 468 } 469 } 470 else { 471 reader.readDBTable( out ); 472 } 473 table = reader.getDBTableModel(); 474 } 475 476 /** 477 * クラウドストレージのExcelファイルをサーバにダウンロード。 478 * (POIで処理する必要があるため) 479 * 480 * @og.rev 5.9.25.2 (2017/10/27) 新規作成 481 * 482 * @param storage クラウドのストレージ 483 * @param container クラウドのコンテナ名 484 * @return filePath サーバのファイルパス 485 */ 486 private String downloadStorageFile(String storage, String container){ 487 String filePath = HybsSystem.url2dir( StringUtil.urlAppend( fileURL,filename )); 488 HttpServletRequest request = (HttpServletRequest)getRequest(); 489 HttpSession hsession = request.getSession(true); 490 StorageAPI storageApi = StorageAPIFactory.newStorageAPI(storage, container, hsession); 491 // ストレージからダウンロード 492 InputStream is = storageApi.get(fileURL + filename, hsession); 493 494 try{ 495 // コピー先ファイルパス 496 File file = new File(filePath); 497 498 // 既にファイルが存在する場合は、削除 499 if(file.exists()){ 500 file.delete(); 501 } 502 503 // ストレージからサーバにファイルコピー 504 Files.copy(is, file.toPath()); 505 506 }catch(IOException e){ 507 String errMsg = "download error:" + e; 508 throw new HybsSystemException(errMsg); 509 } 510 511 return filePath; 512 } 513 514 /** 515 * BufferedReader を取得します。 516 * 517 * ここでは、一般的なファイル出力を考慮した BufferedReader を作成します。 518 * 519 * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 エンコードの取得方法変更 520 * @og.rev 3.1.3.0 (2003/04/10) FILE_ENCODE から、エンコード情報を取得する。 521 * @og.rev 3.5.4.1 (2003/12/01) 引数の BufferedReader を、InputStream に変更。 522 * @og.rev 3.5.4.3 (2004/01/05) 引数の InputStream を、 BufferedReader に戻す。 523 * @og.rev 3.5.5.9 (2004/06/07) FileUtil.getBufferedReader を使用 524 * @og.rev 5.9.25.2 (2017/10/27) クラウドストレージ対応 525 * 526 * @return ファイル読取BufferedReaderオブジェクト 527 */ 528 private BufferedReader getBufferedReader() { 529 if( filename == null ) { 530 String errMsg = "ファイル名がセットされていません。"; 531 throw new HybsSystemException( errMsg ); 532 } 533 534 // 2017/10/20 DELETE 後の判定処理内に移動 535 // 通常の処理 536// String directory = HybsSystem.url2dir( fileURL ); 537// File file = new File( StringUtil.urlAppend( directory,filename ) ); 538// 539// BufferedReader out = FileUtil.getBufferedReader( file,encode ); 540 541 // 5.9.25.2 (2017/10/27) クラウド対応 542 543 BufferedReader out = null; 544 if(CLOUD_STORAGE != null && CLOUD_STORAGE.length() > 0){ 545 // クラウドの場合の処理 546 HttpServletRequest request = (HttpServletRequest)getRequest(); 547 HttpSession hsession = request.getSession(true); 548 StorageAPI storageAPI = StorageAPIFactory.newStorageAPI(CLOUD_STORAGE, CLOUD_CONTAINER, hsession); 549 // クラウドのオブジェクトを読み込み 550 InputStream is = storageAPI.get(fileURL + filename, hsession); 551 try{ 552 out = new BufferedReader(new InputStreamReader(is, encode)); 553 }catch(UnsupportedEncodingException e){ 554 String errMsg = "サポートされていない文字コードです。encode:" + encode; 555 throw new HybsSystemException(errMsg); 556 } 557 }else{ 558 // 通常の処理 559 String directory = HybsSystem.url2dir( fileURL ); 560 File file = new File( StringUtil.urlAppend( directory,filename ) ); 561 562 out = FileUtil.getBufferedReader( file,encode ); 563 } 564 565 return out ; 566 } 567 568 /** 569 * カラム文字列(CSV形式)から、カラム番号配列を作成します。 570 * 簡易メソッドです。 571 * 引数が、"*" の場合は、全カラムを指定したことになります。 572 * null の場合は、サイズが 0 の配列を返します。 573 * 574 * @og.rev 4.0.0.0 (2007/05/25) 新規作成 575 * 576 * @param clms カラム文字列(CSV形式) 577 * @param table DBTableModelオブジェクト 578 * 579 * @return カラム番号配列(無い場合は、長さ0の配列) 580 */ 581 private int[] makeClmNos( final String clms,final DBTableModel table ) { 582 final int[] clmNo; 583 584 if( clms == null ) { 585 clmNo = new int[0]; 586 } 587 else if( "*".equals( clms ) ) { 588 int size = table.getColumnCount(); 589 clmNo = new int[size]; 590 for( int i=0; i<size; i++ ) { 591 clmNo[i] = i; 592 } 593 } 594 else { 595 String[] clmStr = StringUtil.csv2Array( clms ); 596 int size = clmStr.length; 597 clmNo = new int[size]; 598 for( int i=0; i<size; i++ ) { 599 clmNo[i] = table.getColumnNo( clmStr[i] ); 600 } 601 } 602 603 return clmNo; 604 } 605 606 /** 607 * checkColumns に指定されたカラムをチェックします。 608 * カラムオブジェクトのDBType属性に対応したチェックを行います。 609 * チェック結果で、エラーが発生した場合は、ErrorMessage オブジェクトを 610 * 返します。 611 * DBColumn#valueCheck( String ) の結果のErrorMessageをすべて append 612 * していきます。 613 * useAdjust==true で、かつ、エラーがない場合は、adjustColumns 処理結果を 614 * DBTableModel に反映させます。 615 * debug=true で、エラー時の詳細なデータを出力します。 616 * 617 * @og.rev 3.6.0.2 (2004/10/04) 新規作成 618 * @og.rev 3.8.0.2 (2005/06/30) nullチェック確認 619 * @og.rev 4.0.0.0 (2007/05/25) 処理順序書き換え 620 * 621 * @param table DBTableModelオブジェクト 622 * 623 * @return カラムキー + 値 のエラーメッセージオブジェクト 624 */ 625 private ErrorMessage checkTableColumn( final DBTableModel table ) { 626 ErrorMessage errMsg = new ErrorMessage( "Check Columns Error!" ); 627 628 int rowCnt = table.getRowCount(); 629 int[] adjClmNo = makeClmNos( adjustColumns,table ); 630 int[] chkClmNo = makeClmNos( checkColumns,table ); 631 int[] nllclmNo = makeClmNos( nullCheck,table ); 632 633 boolean useAdjust = adjClmNo.length > 0 ; 634 635 for( int row=0; row<rowCnt; row++ ) { 636 String[] vals = table.getValues( row ); 637 DBColumn[] dbClms = table.getDBColumns(); 638 boolean isError = false; // 5.5.7.2 (2012/10/09) エラー時のフラグ。ループでクリアする。 639 640 // adjustColumns 処理 641 for( int i=0; i<adjClmNo.length; i++ ) { 642 int no = adjClmNo[i]; 643 vals[no] = dbClms[no].valueSet( vals[no] ); 644 } 645 646 // checkColumns 処理 647 for( int i=0; i<chkClmNo.length; i++ ) { 648 int no = chkClmNo[i]; 649 ErrorMessage msg = dbClms[no].valueCheck( vals[no] ); 650 if( msg.getKekka() > ErrorMessage.OK ) { 651 isError = true; 652 errMsg.append( row+1,dbClms[no].valueCheck( vals[no] ) ); 653 } 654 } 655 656 // nullCheck 処理 657 for( int i=0; i<nllclmNo.length; i++ ) { 658 int no = nllclmNo[i]; 659 if( vals[no] == null || vals[no].length() == 0 ) { 660 isError = true; 661 String label = dbClms[no].getLabel(); 662 // ERR0012 : 指定のデータがセットされていません。(NULLエラー)。key={0} 663 errMsg.addMessage( row+1,ErrorMessage.NG,"ERR0012",label ); 664 } 665 } 666 667 // 5.5.7.2 (2012/10/09) エラー時のデバッグ出力 668 if( isDebug() && isError ) { 669 errMsg.addMessage( row+1,ErrorMessage.OK,"Debug Info",java.util.Arrays.toString(table.getValues(row) ) ); 670 } 671 672 // adjustColumns 処理結果を反映させます。 673 if( useAdjust && !isError ) { table.setValues( vals,row ); } 674 if( errMsg.size() > ERROR_ROW_COUNT ) { break; } 675 } 676 677 return errMsg; 678 } 679 680 /** 681 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 682 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。 683 * 684 * @og.tag 685 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 686 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 687 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 688 * この tableId 属性を利用して、メモリ空間を分けます。 689 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。 690 * 691 * @param id sessionに登録する時の ID 692 */ 693 public void setTableId( final String id ) { 694 tableId = nval( getRequestParameter( id ), tableId ); 695 } 696 697 /** 698 * 【TAG】可変長ファイルを作成するときの項目区切り文字をセットします。 699 * 700 * @og.tag 可変長ファイルを作成するときの項目区切り文字をセットします。 701 * 702 * @param separator 項目区切り文字 703 */ 704 public void setSeparator( final String separator ) { 705 this.separator = nval( getRequestParameter( separator ),this.separator ); 706 } 707 708 /** 709 * 【TAG】読み取り元ディレクトリ名を指定します 710 * (初期値:FILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])。 711 * 712 * @og.tag 713 * この属性で指定されるディレクトリより、ファイルを読み取ります。 714 * 指定方法は、通常の fileURL 属性と同様に、先頭が、'/' (UNIX) または、2文字目が、 715 * ":" (Windows)の場合は、指定のURLそのままのディレクトリに、そうでない場合は、 716 * fileURL = "{@USER.ID}" と指定すると、FILE_URL 属性で指定のフォルダの下に、 717 * さらに、各個人ID別のフォルダを作成して、そこを操作します。 718 * (初期値:システム定数のFILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])。 719 * 720 * @og.rev 4.0.0.0 (2005/01/31) StringUtil.urlAppend メソッドの利用 721 * @og.rev 4.0.0.0 (2007/11/20) 指定されたディレクトリ名の最後が"\"or"/"で終わっていない場合に、"/"を付加する。 722 * 723 * @param url 読み取り元ディレクトリ名 724 * @see org.opengion.hayabusa.common.SystemData#FILE_URL 725 */ 726 public void setFileURL( final String url ) { 727 String furl = nval( getRequestParameter( url ),null ); 728 if( furl != null ) { 729 char ch = furl.charAt( furl.length()-1 ); 730 if( ch != '/' && ch != '\\' ) { furl = furl + "/"; } 731 fileURL = StringUtil.urlAppend( fileURL,furl ); 732 } 733 } 734 735 /** 736 * 【TAG】ファイルを作成するときのファイル名をセットします 737 * (初期値:FILE_FILENAME[={@og.value org.opengion.hayabusa.common.SystemData#FILE_FILENAME}])。 738 * 739 * @og.tag ファイルを作成するときのファイル名をセットします。 740 * (初期値:システム定数のFILE_FILENAME[={@og.value org.opengion.hayabusa.common.SystemData#FILE_FILENAME}])。 741 * 742 * @param filename ファイル名 743 * @see org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK 744 */ 745 public void setFilename( final String filename ) { 746 this.filename = nval( getRequestParameter( filename ),this.filename ); 747 } 748 749 /** 750 * 【TAG】ファイルを作成するときのファイルエンコーディング名をセットします 751 * (初期値:FILE_ENCODE[={@og.value org.opengion.hayabusa.common.SystemData#FILE_ENCODE}])。 752 * 753 * @og.tag 754 * Shift_JIS,MS932,Windows-31J,UTF-8,ISO-8859-1,UnicodeLittle 755 * (初期値:システム定数のFILE_ENCODE[={@og.value org.opengion.hayabusa.common.SystemData#FILE_ENCODE}])。 756 * 757 * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 エンコードの取得方法変更 758 * @og.rev 3.1.3.0 (2003/04/10) FILE_ENCODE から、エンコード情報を取得する。 759 * 760 * @param enc ファイルエンコーディング名 761 * @see <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a> 762 * @see org.opengion.hayabusa.common.SystemData#FILE_ENCODE 763 */ 764 public void setEncode( final String enc ) { 765 encode = nval( getRequestParameter( enc ),encode ); 766 } 767 768 /** 769 * 【TAG】実際に読み出すクラス名の略称(TableReader_**** の ****)をセットします({@og.doc03Link readerClass 初期値:Default})。 770 * 771 * @og.tag 772 * 実際に読み出すクラス名(の略称)をセットします。 773 * これは、org.opengion.hayabusa.io 以下の TableReader_**** クラスの **** を 774 * 与えます。これらは、TableReader インターフェースを継承したサブクラスです。 775 * 属性クラス定義の {@link org.opengion.hayabusa.io.TableReader TableReader} を参照願います。 776 * {@og.doc03Link readerClass TableReader_**** クラス} 777 * 778 * @param readerClass クラス名(の略称) 779 * @see org.opengion.hayabusa.io.TableReader TableReaderのサブクラス 780 */ 781 public void setReaderClass( final String readerClass ) { 782 this.readerClass = nval( getRequestParameter( readerClass ),this.readerClass ); 783 } 784 785 /** 786 * 【TAG】読取時の最大取り込み件数をセットします 787 * (初期値:DB_MAX_ROW_COUNT[={@og.value org.opengion.hayabusa.common.SystemData#DB_MAX_ROW_COUNT}])。 788 * 789 * @og.tag 790 * DBTableModelのデータとして登録する最大件数をこの値に設定します。 791 * サーバーのメモリ資源と応答時間の確保の為です。 792 * 0 をセットすると、無制限(Integer.MAX_VALUE)になります。 793 * (初期値:ユーザー定数のDB_MAX_ROW_COUNT[={@og.value org.opengion.hayabusa.common.SystemData#DB_MAX_ROW_COUNT}])。 794 * 795 * @og.rev 5.5.8.5 (2012/11/27) 0を無制限として処理します。 796 * 797 * @param count 読取時の最大取り込み件数 798 * @see org.opengion.hayabusa.common.SystemData#DB_MAX_ROW_COUNT 799 */ 800 public void setMaxRowCount( final String count ) { 801 maxRowCount = nval( getRequestParameter( count ),maxRowCount ); 802 if( maxRowCount == 0 ) { maxRowCount = Integer.MAX_VALUE ; } // 5.5.8.5 (2012/11/27) 803 } 804 805 /** 806 * 【TAG】コマンド(NEW,RENEW)をセットします(初期値:NEW)。 807 * 808 * @og.tag 809 * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される 810 * フィールド定数値のいづれかを、指定できます。 811 * 何も設定されない、または、null の場合は、"NEW" が初期値にセットされます。 812 * 813 * @param cmd コマンド(public static final 宣言されている文字列) 814 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ReadTableTag.CMD_NEW">コマンド定数</a> 815 */ 816 public void setCommand( final String cmd ) { 817 String cmd2 = getRequestParameter( cmd ); 818 if( cmd2 != null && cmd2.length() > 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); } 819 } 820 821 /** 822 * 【TAG】query の結果を画面上に表示するメッセージIDを指定します(初期値:MSG0033[ 件検索しました])。 823 * 824 * @og.tag 825 * ここでは、検索結果の件数や登録された件数をまず出力し、 826 * その次に、ここで指定したメッセージをリソースから取得して 827 * 表示します。 828 * 表示させたくない場合は, displayMsg = "" をセットしてください。 829 * 初期値は、検索件数を表示します。 830 * 831 * @param id ディスプレイに表示させるメッセージ ID 832 */ 833 public void setDisplayMsg( final String id ) { 834 if( id != null ) { displayMsg = id; } 835 } 836 837 /** 838 * 【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした])。 839 * 840 * @og.tag 841 * ここでは、検索結果がゼロ件の場合のみ、特別なメッセージを表示させます。 842 * 従来は、displayMsg と兼用で、『0 件検索しました』という表示でしたが、 843 * displayMsg の初期表示は、OFF になりましたので、ゼロ件の場合のみ別に表示させます。 844 * 表示させたくない場合は, notfoundMsg = "" をセットしてください。 845 * 初期値は、MSG0077[対象データはありませんでした]です。 846 * 847 * @param id ディスプレイに表示させるメッセージ ID 848 */ 849 public void setNotfoundMsg( final String id ) { 850 String ids = getRequestParameter( id ); 851 if( ids != null ) { notfoundMsg = ids; } 852 } 853 854 /** 855 * 【TAG】ファイル取り込み時の モディファイタイプ(A(追加),C(更新),D(削除))を指定します。 856 * 857 * @og.tag 858 * ファイル読み込み時に、そのデータをA(追加)、C(更新)、D(削除)の 859 * モディファイタイプをつけた状態にします。 860 * その状態で、そのまま、update する事が可能になります。 861 * 862 * @param type ファイル取り込み時の モディファイタイプ(A,C,D属性) 863 */ 864 public void setModifyType( final String type ) { 865 modifyType = getRequestParameter( type ); 866 } 867 868 /** 869 * 【TAG】EXCELファイルを読み込むときのシート名を設定します(初期値:指定なし)。 870 * 871 * @og.tag 872 * EXCELファイルを読み込む時に、シート名を指定します。これにより、複数の形式の 873 * 異なるデータを順次読み込むことや、シートを指定して読み取ることが可能になります。 874 * sheetNos と sheetName が同時に指定された場合は、sheetNos が優先されます。エラーにはならないのでご注意ください。 875 * 初期値は、指定なしです。 876 * 877 * @og.rev 3.5.4.2 (2003/12/15) 新規追加 878 * 879 * @param sheet EXCELファイルのシート名 880 * @see #setSheetNos( String ) 881 */ 882 public void setSheetName( final String sheet ) { 883 sheetName = nval( getRequestParameter( sheet ),sheetName ); 884 } 885 886 /** 887 * 【TAG】EXCELファイルを読み込むときのシート番号を指定します(初期値:0)。 888 * 889 * @og.tag 890 * EXCEL読み込み時に複数シートをマージして取り込みます。 891 * シート番号は、0 から始まる数字で表します。 892 * ヘッダーは、最初のシートのカラム位置に合わせます。(ヘッダータイトルの自動認識はありません。) 893 * よって、指定するシートは、すべて同一レイアウトでないと取り込み時にカラムのずれが発生します。 894 * 895 * シート番号の指定は、カンマ区切りで、複数指定できます。また、N-M の様にハイフンで繋げることで、 896 * N 番から、M 番のシート範囲を一括指定可能です。また、"*" による、全シート指定が可能です。 897 * これらの組み合わせも可能です。( 0,1,3,5-8,10-* ) 898 * ただし、"*" に関しては例外的に、一文字だけで、すべてのシートを表すか、N-* を最後に指定するかの 899 * どちらかです。途中には、"*" は、現れません。 900 * シート番号は、重複(1,1,2,2)、逆転(3,2,1) での指定が可能です。これは、その指定順で、読み込まれます。 901 * sheetNos と sheetName が同時に指定された場合は、sheetNos が優先されます。エラーにはならないのでご注意ください。 902 * 903 * 初期値は、0(第一シート) です。 904 * 905 * @og.rev 5.5.7.2 (2012/10/09) 新規追加 906 * 907 * @param sheet EXCELファイルのシート番号(0から始まる) 908 * @see #setSheetName( String ) 909 */ 910 public void setSheetNos( final String sheet ) { 911 sheetNos = nval( getRequestParameter( sheet ),sheetNos ); 912 if( sheetNos != null && sheetNos.length() > 0 ) { 913 boolean errFlag = false; 914 for( int i=0; i<sheetNos.length(); i++ ) { 915 char ch = sheetNos.charAt(i); 916 if( ch == '-' || ch == ',' ) { continue; } 917 if( ch == '*' && ( i==0 || i==sheetNos.length()-1 ) ) { continue; } 918 if( ch < '0' || ch > '9' ) { errFlag = true; break; } 919 } 920 if( errFlag ) { 921 String errMsg = "sheetNos の指定を見直してください。sheetNos=[" + sheetNos + "]"; 922 throw new HybsSystemException( errMsg ); 923 } 924 } 925 } 926 927 /** 928 * 【TAG】EXCELファイルを読み込むときのシート単位の固定値を設定するためのカラム名を指定します。 929 * 930 * @og.tag 931 * カラム名は、カンマ区切りで指定します。 932 * これにより、シートの一か所に書かれている情報を、DBTableModel のカラムに固定値として 933 * 設定することができます。 934 * 例として、DB定義書で、テーブル名をシートの全レコードに設定したい場合などに使います。 935 * このメソッドは、isExcel() == true の場合のみ利用されます。 936 * 937 * @og.rev 5.5.8.2 (2012/11/09) 新規追加 938 * 939 * @param constKeys 固定値となるカラム名(CSV形式) 940 * @see #setSheetConstAdrs( String ) 941 */ 942 public void setSheetConstKeys( final String constKeys ) { 943 sheetConstKeys = nval( getRequestParameter( constKeys ),null ); 944 } 945 946 /** 947 * 【TAG】EXCELファイルを読み込むときのシート単位の固定値を設定するためのカラム名に対応するアドレスを指定します。 948 * 949 * @og.tag 950 * アドレスは、EXCEL上の行-列をカンマ区切りで指定します。 951 * 行列は、EXCELオブジェクトに準拠するため、0から始まる整数です。 952 * 0-0 ⇒ A1 , 1-0 ⇒ A2 , 0-1 ⇒ B1 になります。 953 * これにより、シートの一か所に書かれている情報を、DBTableModel のカラムに固定値として 954 * 設定することができます。 955 * 例として、DB定義書で、テーブル名をシートの全レコードに設定したい場合などに使います。 956 * このメソッドは、isExcel() == true の場合のみ利用されます。 957 * 958 * 5.7.6.3 (2014/05/23) より、 959 * @EXCEL表記に準拠した、A1,A2,B1 の記述も処理できるように対応します。 960 * なお、A1,A2,B1 の記述は、必ず、英字1文字+数字 にしてください。(A〜Zまで) 961 * A処理中のEXCELシート名をカラムに割り当てるために、"SHEET" という記号に対応します。 962 * 例えば、sheetConstKeys="CLM,LANG,NAME" とし、sheetConstAdrs="0-0,A2,SHEET" とすると、 963 * NAMEカラムには、シート名を読み込むことができます。 964 * これは、内部処理の簡素化のためです。 965 * 966 * ちなみに、EXCELのセルに、シート名を表示させる場合の関数は、下記の様になります。 967 * =RIGHT(CELL("filename",$A$1),LEN(CELL("filename",$A$1))-FIND("]",CELL("filename",$A$1))) 968 * 969 * @og.rev 5.5.8.2 (2012/11/09) 新規追加 970 * 971 * @param constAdrs 固定値となるアドレス(行-列,行-列,・・・) 972 * @see #setSheetConstKeys( String ) 973 */ 974 public void setSheetConstAdrs( final String constAdrs ) { 975 sheetConstAdrs = nval( getRequestParameter( constAdrs ),null ); 976 } 977 978 /** 979 * 【TAG】ここに指定されたカラム列に NULL が現れた時点で読み取りを中止します。 980 * 981 * @og.tag 982 * これは、指定のカラムは必須という事を条件に、そのレコードだけを読み取る処理を行います。 983 * 複数Sheetの場合は、次のSheetを読みます。 984 * 現時点では、Excel の場合のみ有効です。 985 * 986 * @og.rev 5.5.8.2 (2012/11/09) 新規追加 987 * 988 * @param clm カラム列 989 */ 990 public void setNullBreakClm( final String clm ) { 991 nullBreakClm = nval( getRequestParameter( clm ),null ); 992 } 993 994 /** 995 * 【TAG】読み取り元ファイルのカラム列を、外部(タグ)より指定します。 996 * 997 * @og.tag 998 * 読み取り元ファイルのカラム列を、外部(タグ)より指定します。 999 * ファイルに記述された #NAME より優先して使用されます。 1000 * これは、元ファイルのカラムを順番に指定のカラム名に割り当てる機能で 1001 * ファイルの特定のカラム列を抜き出して取り込む機能ではありません。 1002 * 1003 * @og.rev 3.5.4.5 (2004/01/23) 新規作成 1004 * 1005 * @param clms 読み取り元ファイルのカラム列(カンマ区切り文字) 1006 */ 1007 public void setColumns( final String clms ) { 1008 columns = nval( getRequestParameter( clms ),columns ); 1009 } 1010 1011 /** 1012 * 【TAG】読み取り元ファイルの整合性チェックを行うカラム列をカンマ指定します。 1013 * 1014 * @og.tag 1015 * カラムオブジェクトのDBType属性に対応したチェックを行います。 1016 * 指定のカラム名をカンマ区切り(CSV)で複数指定できます。 1017 * 全てのカラムのチェックを行う場合は、allColumnCheck = "true" を 1018 * 指定して下さい。 1019 * 分解方法は、通常のパラメータ取得後に、CSV分解します。 1020 * 1021 * @og.rev 3.6.0.2 (2004/10/04) 新規追加 取り込み時チェック用 1022 * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSV分解に戻します。 1023 * 1024 * @param clms 整合性チェックを行うカラム列(カンマ区切り文字) 1025 */ 1026 public void setCheckColumns( final String clms ) { 1027 checkColumns = nval( getRequestParameter( clms ),checkColumns ); 1028 } 1029 1030 /** 1031 * 【TAG】読み取り元ファイルのデータ変換を行うカラム列をカンマ指定します。 1032 * 1033 * @og.tag 1034 * カラムオブジェクトのDBType属性に対応したデータ変換を行います。 1035 * 指定のカラム名をカンマ区切り(CSV)で複数指定できます。 1036 * 分解方法は、通常のパラメータ取得後に、CSV分解します。 1037 * 1038 * @og.rev 3.6.0.2 (2004/10/04) 新規追加 取り込み時データ変換 1039 * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSV分解に戻します。 1040 * 1041 * @param clms データ変換を行うカラム列(カンマ区切り文字) 1042 */ 1043 public void setAdjustColumns( final String clms ) { 1044 adjustColumns = nval( getRequestParameter( clms ),adjustColumns ); 1045 } 1046 1047 /** 1048 * 【TAG】NULL チェックすべきカラム列をカンマ区切り(CVS形式)で指定します。 1049 * 1050 * @og.tag nullCheck="AAA,BBB,CCC,DDD" 1051 * 分解方法は、通常のパラメータ取得後に、CSV分解します。 1052 * 1053 * @og.rev 3.8.0.2 (2005/06/30) 新規追加 1054 * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSV分解に戻します。 1055 * 1056 * @param clms カラム列(CVS形式) 1057 */ 1058 public void setNullCheck( final String clms ) { 1059 nullCheck = nval( getRequestParameter( clms ),nullCheck ); 1060 } 1061 1062 /** 1063 * 【TAG】行番号情報を、使用している/していない[true/false]を指定します(初期値:true)。 1064 * 1065 * @og.tag 1066 * 通常のフォーマットでは、各行の先頭に行番号が出力されています。 1067 * 読み取り時に、#NAME 属性を使用する場合は、この行番号を無視しています。 1068 * #NAME 属性を使用せず、columns 属性でカラム名を指定する場合(他システムの 1069 * 出力ファイルを読み取るケース等)では、行番号も存在しないケースがあり、 1070 * その様な場合に、useNumber="false" を指定すれば、データの最初から読み取り始めます。 1071 * この場合、出力データのカラムの並び順が変更された場合、columns 属性も 1072 * 指定しなおす必要がありますので、できるだけ、#NAME 属性を使用するように 1073 * してください。 1074 * なお、EXCEL 入力には、この設定は適用されません。(暫定対応) 1075 * 初期値は、true(使用する) です。 1076 * 1077 * @og.rev 3.7.0.5 (2005/04/11) 新規追加 1078 * 1079 * @param useNo 行番号情報 [true:使用する/false:使用しない] 1080 */ 1081 public void setUseNumber( final String useNo ) { 1082 useNumber = nval( getRequestParameter( useNo ),useNumber ); 1083 } 1084 1085 /** 1086 * 【TAG】読込件数が0件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する])。 1087 * 1088 * @og.tag 1089 * 初期値は、false(続行する)です。 1090 * 1091 * @og.rev 4.3.7.0 (2009/06/01) 新規追加 1092 * 1093 * @param cmd 読込件数が0件のとき、処理を [true:中止する/false:続行する] 1094 */ 1095 public void setStopZero( final String cmd ) { 1096 stopZero = nval( getRequestParameter( cmd ), stopZero ); 1097 } 1098 1099 /** 1100 * 【TAG】(通常使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します(初期値:false)。 1101 * 1102 * @og.tag 1103 * この値は、ファイルダウンロード処理に影響します。この値がtrueに指定された時にcommitされたDBTableModelが 1104 * ファイルダウンロードの対象の表になります。 1105 * 1106 * このパラメーターは、通常、各タグにより実装され、ユーザーが指定する必要はありません。 1107 * 但し、1つのJSP内でDBTableModelが複数生成される場合に、前に処理したDBTableModelについてファイルダウンロードをさせたい 1108 * 場合は、後ろでDBTableModelを生成するタグで、明示的にこの値をfalseに指定することで、ファイルダウンロード処理の対象から 1109 * 除外することができます。 1110 * 1111 * @og.rev 5.1.6.0 (2010/05/01) 新規作成 1112 * 1113 * @param flag メイントランザクションかどうか 1114 */ 1115 public void setMainTrans( final String flag ) { 1116 isMainTrans = nval( getRequestParameter( flag ),isMainTrans ); 1117 } 1118 1119 /** 1120 * 【TAG】(通常は使いません)データの読み飛ばし件数を設定します。 1121 * 1122 * @og.tag 1123 * TAB区切りテキストやEXCEL等のデータの読み始めの初期値を指定します。 1124 * ファイルの先頭行が、0行としてカウントしますので、設定値は、読み飛ばす 1125 * 件数になります。(1と指定すると、1件読み飛ばし、2行目から読み込みます。) 1126 * 読み飛ばしは、コメント行などは、無視しますので、実際の行数分読み飛ばします。 1127 * #NAME属性や、columns 属性は、有効です。 1128 * 1129 * @og.rev 5.1.6.0 (2010/05/01) 新規作成 1130 * 1131 * @param count 読み始めの初期値 1132 */ 1133 public void setSkipRowCount( final String count ) { 1134 skipRowCount = nval( getRequestParameter( count ),skipRowCount ); 1135 } 1136 1137 /** 1138 * 【TAG】読取処理でラベルをコードリソースに逆変換を行うかどうかを指定します 1139 * (初期値:USE_TABLE_READER_RENDERER[={@og.value org.opengion.hayabusa.common.SystemData#USE_TABLE_READER_RENDERER}])。 1140 * 1141 * @og.tag 1142 * TableWriter_Renderer 系のクラスで出力した場合は、コードリソースがラベルで出力されます。 1143 * そのファイルを読み取ると、当然、エラーになります。 1144 * ここでは、コードリソースのカラムに対して、ラベルからコードを求める逆変換を行うことで、 1145 * Renderer 系で出力したファイルを取り込むことができるようにします。 1146 * 1147 * ここでは、TableWriter 系と同様に、TableReader_Renderer 系のクラスを作るのではなく、 1148 * 属性値のフラグで、制御します。 1149 * 将来的には、TableWriter 系も廃止して、同様のフラグで制御するように変更する予定です。 1150 * (初期値:システム定数のUSE_TABLE_READER_RENDERER[={@og.value org.opengion.hayabusa.common.SystemData#USE_TABLE_READER_RENDERER}])。 1151 * 1152 * @og.rev 5.2.1.0 (2010/10/01) 新規作成 1153 * 1154 * @param flag コードリソースのラベル逆変換を行うかどうか 1155 * @see org.opengion.hayabusa.common.SystemData#USE_TABLE_READER_RENDERER 1156 */ 1157 public void setUseRenderer( final String flag ) { 1158 useRenderer = nval( getRequestParameter( flag ),useRenderer ); 1159 } 1160 1161 /** 1162 * 【TAG】matchKeysをカンマ区切りで指定します。 1163 * 1164 * @og.tag 1165 * ファイルから特定の行のみを読み取るためのmatchKeysを指定します。 1166 * matchKeysで指定したカラムに対して、matchValsの正規表現でチェックします。 1167 * この機能はTableReader_Defaultのみ有効です。 1168 * 通常は指定する必要はありません。 1169 * 1170 * 1171 * @og.rev 5.9.8.1 (2016/05/13) 新規作成 1172 * 1173 * @param keys カラム列(カンマ区切り文字) 1174 */ 1175 public void setMatchKeys( final String keys ) { 1176 matchKeys = getCSVParameter( keys ); 1177 1178 if( matchVals != null && matchKeys.length != matchVals.length ) { 1179 String errMsg = "matchKeys属性とmatchVals属性の個数が合いません。" 1180 + HybsSystem.CR 1181 + " matchKeys=[" + matchKeys.length + "]:KEYS=" 1182 + StringUtil.array2csv( matchKeys ) + HybsSystem.CR 1183 + " matchVals=[" + matchVals.length + "]:VLAS=" 1184 + StringUtil.array2csv( matchVals ) + HybsSystem.CR ; 1185 throw new HybsSystemException( errMsg ); 1186 } 1187 } 1188 1189 /** 1190 * 【TAG】matchKeysをカンマ区切りで指定します。 1191 * 1192 * @og.tag 1193 * ファイルから特定の行のみを読み取るためのmatchKeysを指定します。 1194 * matchKeysで指定したカラムに対して、matchValsの正規表現でチェックします。 1195 * この機能はTableReader_Defaultのみ有効です。 1196 * 通常は指定する必要はありません。 1197 * 1198 * 1199 * @og.rev 5.9.8.1 (2016/05/13) 新規作成 1200 * 1201 * @param keys カラム列(カンマ区切り文字) 1202 */ 1203 public void setMatchVals( final String keys ) { 1204 matchVals = getCSVParameter( keys ); 1205 1206 if( matchKeys != null && matchKeys.length != matchVals.length ) { 1207 String errMsg = "matchKeys属性とmatchVals属性の個数が合いません。" 1208 + HybsSystem.CR 1209 + " matchKeys=[" + matchKeys.length + "]:KEYS=" 1210 + StringUtil.array2csv( matchKeys ) + HybsSystem.CR 1211 + " matchVals=[" + matchVals.length + "]:VLAS=" 1212 + StringUtil.array2csv( matchVals ) + HybsSystem.CR ; 1213 throw new HybsSystemException( errMsg ); 1214 } 1215 } 1216 1217 /** 1218 * シリアライズ用のカスタムシリアライズ書き込みメソッド 1219 * 1220 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 1221 * @serialData 一部のオブジェクトは、シリアライズされません。 1222 * 1223 * @param strm ObjectOutputStreamオブジェクト 1224 * @throws IOException 入出力エラーが発生した場合 1225 */ 1226 private void writeObject( final ObjectOutputStream strm ) throws IOException { 1227 strm.defaultWriteObject(); 1228 } 1229 1230 /** 1231 * シリアライズ用のカスタムシリアライズ読み込みメソッド 1232 * 1233 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。 1234 * 1235 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 1236 * @serialData 一部のオブジェクトは、シリアライズされません。 1237 * 1238 * @param strm ObjectInputStreamオブジェクト 1239 * @see #release2() 1240 * @throws IOException シリアライズに関する入出力エラーが発生した場合 1241 * @throws ClassNotFoundException クラスを見つけることができなかった場合 1242 */ 1243 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 1244 strm.defaultReadObject(); 1245 } 1246 1247 /** 1248 * このオブジェクトの文字列表現を返します。 1249 * 基本的にデバッグ目的に使用します。 1250 * 1251 * @return このクラスの文字列表現 1252 */ 1253 @Override 1254 public String toString() { 1255 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 1256 .println( "VERSION" ,VERSION ) 1257 .println( "separator" ,separator ) 1258 .println( "fileURL" ,fileURL ) 1259 .println( "filename" ,filename ) 1260 .println( "encode" ,encode ) 1261 .println( "readerClass" ,readerClass ) 1262 .println( "maxRowCount" ,maxRowCount ) 1263 .println( "displayMsg" ,displayMsg ) 1264 .println( "executeCount" ,executeCount ) 1265 .println( "modifyType" ,modifyType ) 1266 .println( "checkColumns" ,checkColumns ) 1267 .println( "adjustColumns" ,adjustColumns ) 1268 .println( "nullCheck" ,nullCheck ) 1269 .println( "command" ,command ) 1270 .println( "tableId" ,tableId ) 1271 .println( "sheetName" ,sheetName ) 1272 .println( "sheetNos" ,sheetNos ) // 5.5.7.2 (2012/10/09) 1273 .println( "columns" ,columns ) 1274 .println( "useNumber" ,useNumber ) 1275 .println( "Other..." ,getAttributes().getAttribute() ) 1276 .fixForm().toString() ; 1277 } 1278}