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 */
016 package org.opengion.hayabusa.taglib;
017
018 import org.opengion.hayabusa.common.HybsSystem;
019 import org.opengion.hayabusa.common.HybsSystemException;
020 import org.opengion.hayabusa.resource.ResourceManager;
021 import org.opengion.hayabusa.resource.GUIInfo;
022 import org.opengion.hayabusa.db.DBColumn;
023 import org.opengion.fukurou.db.Transaction;
024 import org.opengion.fukurou.db.TransactionReal;
025 import org.opengion.fukurou.util.FileUtil;
026 import org.opengion.fukurou.util.ErrorMessage;
027 import org.opengion.fukurou.util.StringUtil;
028 import org.opengion.fukurou.util.Closer ;
029 import org.opengion.fukurou.model.Formatter;
030 import org.opengion.fukurou.model.ArrayDataModel;
031
032 import static org.opengion.fukurou.util.StringUtil.nval ;
033
034 import java.sql.Connection;
035 import java.sql.PreparedStatement;
036 import java.sql.SQLException;
037
038 import java.io.File;
039 import java.io.BufferedReader;
040 import java.io.IOException;
041
042 /**
043 * æŒ?®šã?ファイルを直接ãƒ??タベã?スに登録するãƒ??タ入力タグですã?
044 *
045 * 通常の readTable などは、DBTableModelオブジェクトを介して全件メモリに
046 * ロードしてから表示させる為、大量データ処ç�?�Œできませんã€?
047 * こã?タグでは、直接ファイルを読み取りながらãƒ??タベã?ス登録するので
048 * 大量データをバãƒ?ƒ�çš?�«登録する場合に使用しますã?
049 *
050 * 読み取るファイルは、å?頭(またã?実データが現れるまでに) #NAME 行がå¿?¦�ですã?
051 * これは、ファイルãƒ??タのカラãƒ?��を指定してã�?�¾すã?またã?columns 属æ?を使用すればã€?
052 * ファイルの#NAME 行より優先して(つまり存在してã�?�ªくても良ã�?ãƒ??タのカラãƒ?��ã‚?
053 * æŒ?®šすることがå?来ますã?
054 * こã?#NAME 行ã?、ファイルのセパレータと無関係にå¿?�šタブ区åˆ?‚Šで用意されてã�?�¾すã?
055 * タグのBODY部に、実行するSQLæ–?‚’記述しますã?
056 * こã?SQLæ–??ã€?
057 * INSERT INTO GE41 (CLM,NAME_JA,SYSTEM_ID,FGJ,DYSET)
058 * VALUES ([CLM],[NAME_JA],[SYSTEM_ID],'1','{@USER.YMDH}')
059 * と、いã�?„Ÿじで、ファイルから読み込んだ値は、[カラãƒ?��]に割り当てられますã?
060 * もちろんã€??常の固定å?(FGJに'1'をセãƒ?ƒˆ)ã‚??リクエスト変数(DYSETの{@USER.YMDH})
061 * なども使用できますã?
062 *
063 * ※ こã?タグは、Transaction タグの対象ですã?
064 *
065 * @og.formSample
066 * ●形式ï¼?lt;og:directTableInsert filename="[?¥?¥?¥]" ?¥?¥?¥ >INSERT INTO ?¥?¥?¥ </og:directTableInsert >
067 * ●body?šあã‚?EVAL_BODY_BUFFERED:BODYを評価しã?{@XXXX} を解析しまã�?
068 *
069 * ●Tag定義??
070 * <og:directTableInsert
071 * fileURL 【TAG】読み取りå…?ƒ‡ィレクトリ名をæŒ?®šしまã�?(初期値:FILE_URL[=filetemp/])
072 * filename 【TAG】ファイルを作æ?するときã?ファイル名をセãƒ?ƒˆしまã�?(初期値:FILE_FILENAME[=file.xls])
073 * encode 【TAG】ファイルを作æ?するときã?ファイルエンコーãƒ?‚£ング名をセãƒ?ƒˆしまã�?(初期値:FILE_ENCODE[=UnicodeLittle])
074 * separator 【TAG】可変長ファイルを作æ?するときã?é ?›®区åˆ?‚Šæ–?—をセãƒ?ƒˆしまã�?初期値:タãƒ?
075 * displayMsg 【TAG】query の結果を画面上に表示するメãƒ?‚»ージIDを指定しまã�?初期値:MSG0040[ã€?»¶登録しました])
076 * columns 【TAGã€?NAME 属æ?の代わりとなるファイルのカラãƒ?��ã‚?CSV形式でæŒ?®šしまã�?
077 * commitBatch 【TAG】指定数毎にコミットを発行しまã�?初期値:0 終äº?�¾でコミットしません)
078 * useColumnAdjust 【TAG】カラãƒ?¤‰換(DBType変換)を行うかどã�?�‹を設定しまã�?初期値:false)
079 * useColumnCheck 【TAG】カラãƒ?ƒ�ェãƒ?‚¯(DBTypeチェãƒ?‚¯)を行うかどã�?�‹を設定しまã�?初期値:false)
080 * nullCheck 【TAG】NULL チェãƒ?‚¯すべきカラãƒ??をカンマ区åˆ?‚Š(CSV形å¼?でæŒ?®šしまã�?
081 * dbid 【TAGã€?通常は使ã�?�¾せん)検索時ã?DB接続IDを指定しまã�?初期値:DEFAULT)
082 * skipRowCount 【TAG】データの読み飛ã?し件数を設定しまã�?初期値:0)
083 * debug 【TAG】デバッグæƒ??をå?力するかどã�?�‹[true/false]を指定しまã�?初期値:false)
084 * > ... Body ...
085 * </og:directTableInsert>
086 *
087 * ●使用ä¾?
088 * <og:directTableInsert
089 * dbid = "ORCL" 接続データベã?スID(初期値:DEFAULT)
090 * separator = "," ファイルの区åˆ?‚Šæ–??初期値:タãƒ?
091 * fileURL = "{@USER.ID}" 読み取りå…?ƒ‡ィレクトリå�?
092 * filename = "{@filename}" 読み取りå…?ƒ•ァイルå�?
093 * encode = "Shift_JIS" 読み取りå…?ƒ•ァイルエンコード名
094 * displayMsg = "MSG0040" 登録完äº?¾Œã?メãƒ?‚»ージ
095 * columns = "CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG"
096 * #NAME の代わりに使用するカラãƒ??å�?
097 * commitBatch = "100" こã?件数ずつコミットを発è¡?初期値:無制é™?
098 * useColumnCheck = "true" カラãƒ?ƒ�ェãƒ?‚¯を行うかどã�?�‹(初期値:false)
099 * useColumnAdjust = "true" カラãƒ?¤‰換を行うかどã�?�‹(初期値:false)
100 * nullCheck = "CLM,SYSTEM_ID" NULLチェãƒ?‚¯を実行しますã?
101 * >
102 * INSERT INTO GE41
103 * (CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG,
104 * FGJ,DYSET,DYUPD,USRSET,USRUPD,PGUPD)
105 * VALUES
106 * ([CLM],[NAME_JA],[LABEL_NAME],[KBSAKU],[SYSTEM_ID],[LANG],
107 * '1','{@USER.YMDH}','{@USER.YMDH}','{@USER.ID}','{@USER.ID}','{@GUI.KEY}')
108 * </og:directTableInsert >
109 *
110 * @og.group ファイル入åŠ?
111 *
112 * @version 4.0
113 * @author Kazuhiko Hasegawa
114 * @since JDK5.0,
115 */
116 public class DirectTableInsertTag extends CommonTagSupport {
117 //* こã?プログラãƒ??VERSIONæ–?—å?を設定しますã? {@value} */
118 private static final String VERSION = "5.5.7.1 (2012/10/05)" ;
119
120 private static final long serialVersionUID = 557120121005L ;
121
122 private static final String TAB_SEPARATOR = "\t" ;
123
124 // 4.0.0.0 (2007/10/10) dbid の初期値をã?"DEFAULT" から null に変更
125 // private String dbid = "DEFAULT";
126 private String dbid = null;
127 private String separator = TAB_SEPARATOR; // é ?›®区åˆ?‚Šæ–??
128 private String fileURL = HybsSystem.sys( "FILE_URL" ); // 4.0.0 (2005/01/31)
129 private String filename = HybsSystem.sys( "FILE_FILENAME" ); // ファイルå�?
130 private String encode = HybsSystem.sys( "FILE_ENCODE" ); // ファイルエンコーãƒ?‚£ング "JISAutoDetect" ,"JIS", "EUC_JP", "MS932", "SJIS" , "Windows-31J" , "Shift_JIS"
131 private String displayMsg = "MSG0040"; // ã€?»¶登録しましたã€?
132 private String[] columns = null;
133 private String[] clmKeys = null; // SQLæ–??[カラãƒ?��]配å?
134 private String sql = null;
135 private int commitBatch = 0; // コミットするまとめ件数
136 private boolean useColumnCheck = false; // 3.6.0.2 (2004/10/04)
137 private boolean useColumnAdjust = false; // 3.6.0.2 (2004/10/04)
138 private String[] nullCheck = null; // 3.8.0.2 (2005/06/30) nullチェãƒ?‚¯確èª?
139 private long dyStart = 0; // 実行時間測定用のDIV要ç´?‚’出力しますã?
140 private int skipRowCount = 0; // 5.5.7.1 (2012/10/01)
141
142 /**
143 * Taglibの開始タグが見つかったときに処ç�?�™ã‚?doStartTag() ã‚?オーバã?ライドしますã?
144 *
145 * @return 後続å?ç�??æŒ?¤º( EVAL_BODY_BUFFERED )
146 */
147 @Override
148 public int doStartTag() {
149 dyStart = System.currentTimeMillis(); // 時間測定用
150 return( EVAL_BODY_BUFFERED ); // Body を評価するã€? extends BodyTagSupport æ™?
151 }
152
153 /**
154 * Taglibのタグ本体を処ç�?�™ã‚?doAfterBody() ã‚?オーバã?ライドしますã?
155 *
156 * @og.rev 3.6.0.2 (2004/10/04) SQLæ–?? [カラãƒ? 対応とパã?サー機è?追åŠ?
157 * @og.rev 3.8.6.3 (2006/11/30) SQL æ–??前後ã?スペã?スを取り除きますã?
158 *
159 * @return 後続å?ç�??æŒ?¤º(SKIP_BODY)
160 */
161 @Override
162 public int doAfterBody() {
163 sql = getBodyString();
164 if( sql == null || sql.length() == 0 ) {
165 String errMsg = "BODY 部の登録用 Insert/Updateæ–??、å¿??ですã?";
166 throw new HybsSystemException( errMsg );
167 }
168 // 3.6.0.2 (2004/10/04) SQLæ–?? [カラãƒ? 対応とパã?サー機è?追åŠ?
169 // sql = makeFormat( sql.trim() ); // ここで、clmLeys 配å?もセãƒ?ƒˆされるã?
170
171 return(SKIP_BODY); // Body を評価しなã�?
172 }
173
174 /**
175 * Taglibの終äº?‚¿グが見つかったときに処ç�?�™ã‚?doEndTag() ã‚?オーバã?ライドしますã?
176 *
177 * @og.rev 4.0.0.0 (2007/10/18) メãƒ?‚»ージリソース統å�? getResource().getMessage > getResource().getLabel )
178 *
179 * @return 後続å?ç�??æŒ?¤º
180 */
181 @Override
182 public int doEndTag() {
183 debugPrint(); // 4.0.0 (2005/02/28)
184
185 BufferedReader pw = getBufferedReader();
186 int executeCount = create( pw );
187 Closer.ioClose( pw ); // 4.0.0 (2006/01/31) close 処ç�?™‚の IOException を無è¦?
188
189 // 実行件数の表示
190 // 4.0.0 (2005/11/30) 出力é?の変更。ä¸?•ªæœ??に出力しますã?
191 if( displayMsg != null && displayMsg.length() > 0 ) {
192 // String status = executeCount + getResource().getMessage( displayMsg ) ;
193 String status = executeCount + getResource().getLabel( displayMsg ) ;
194 jspPrint( status + HybsSystem.BR );
195 }
196
197 // 時間測定用の DIV 要ç´?‚’出åŠ?
198 long dyTime = System.currentTimeMillis()-dyStart;
199 jspPrint( "<div id=\"queryTime\" value=\"" + (dyTime) + "\"></div>" ); // 3.5.6.3 (2004/07/12)
200
201 // 4.0.0 (2005/01/31) セキュリãƒ?‚£チェãƒ?‚¯(ãƒ??タアクセス件数登録)
202 GUIInfo guiInfo = (GUIInfo)getSessionAttribute( HybsSystem.GUIINFO_KEY );
203 if( guiInfo != null ) { guiInfo.addWriteCount( executeCount,dyTime,sql ); }
204
205 return(EVAL_PAGE);
206 }
207
208 /**
209 * タグリブオブジェクトをリリースしますã?
210 * キャãƒ?‚·ュされて再利用されるã?で、フィールドã?初期設定を行いますã?
211 *
212 * @og.rev 3.6.0.2 (2004/10/04) useColumnCheck,useColumnAdjust 属æ?追åŠ?
213 * @og.rev 3.8.0.2 (2005/06/30) nullCheck 属æ?追åŠ?
214 * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値をã?"DEFAULT" から null に変更
215 * @og.rev 5.5.7.1 (2012/10/05) skipRowCount追åŠ?
216 */
217 @Override
218 protected void release2() {
219 super.release2();
220 dbid = null;
221 separator = TAB_SEPARATOR; // é ?›®区åˆ?‚Šæ–??
222 fileURL = HybsSystem.sys( "FILE_URL" ); // 4.0.0 (2005/01/31)
223 filename = HybsSystem.sys( "FILE_FILENAME" ); // ファイルå�?
224 encode = HybsSystem.sys( "FILE_ENCODE" ); // ファイルエンコーãƒ?‚£ング "JISAutoDetect" ,"JIS", "EUC_JP", "MS932", "SJIS" , "Windows-31J" , "Shift_JIS"
225 displayMsg = "MSG0040"; // ã€?»¶登録しましたã€?
226 columns = null; // 3.5.4.5 (2004/01/23)
227 useColumnCheck = false; // 3.6.0.2 (2004/10/04)
228 useColumnAdjust = false; // 3.6.0.2 (2004/10/04)
229 nullCheck = null; // 3.8.0.2 (2005/06/30)
230 skipRowCount = 0; // 5.5.7.1 (2012/10/05)
231 }
232
233 /**
234 * BufferedReader より読み込み、データベã?スに書き込みますã?
235 *
236 * @og.rev 3.6.0.2 (2004/10/04) カラãƒ?‚ªブジェクトã?DBType属æ?の整合æ?チェãƒ?‚¯
237 * @og.rev 3.8.0.2 (2005/06/30) nullチェãƒ?‚¯確èª?
238 * @og.rev 3.8.5.1 (2006/05/08) 取込ãƒ??タã�?name 列より少なã�??合ã?対応を追åŠ?
239 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得ã?為,ApplicationInfoオブジェクトを設å®?
240 * @og.rev 4.0.0.0 (2005/01/31) CheckColumnDataクラス static 化ã?引数にResourceManager追åŠ?
241 * @og.rev 4.0.0.1 (2007/12/03) try ??catch ??finally をきちんと行うã€?
242 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対å¿?
243 * @og.rev 5.2.2.0 (2010/11/01)) ""で囲われてã�?‚‹ãƒ??タに改行が入ってã�?�Ÿ場合ã?対å¿?
244 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
245 * @og.rev 5.3.8.0 (2011/08/01) pstmt.setObject で、useParamMetaData の判定を避けるため、pstmt.setString で代用(PostgreSQL対å¿?
246 * @og.rev 5.5.7.1 (2012/10/05) omitFirstLine対å¿?
247 *
248 * @param reader BufferedReaderオブジェクãƒ?
249 *
250 * @return 取り込み件数
251 */
252 private int create( final BufferedReader reader ) {
253
254 String[] names = readName( reader ); // ファイルのカラãƒ?��
255 int nameLen = names.length ; // 3.8.5.1 (2006/05/08) 追åŠ?
256 // int[] clmNos = getColumnNos( names, clmKeys ); // バインド変数のアドレス求め
257 // int clmNosLen = clmNos.length ;
258
259 ArrayDataModel nmdata = new ArrayDataModel( names );
260 Formatter format = new Formatter( nmdata );
261 format.setFormat( sql.trim() );
262 sql = format.getQueryFormatString();
263 int[] clmNos = format.getClmNos();
264 int clmNosLen = clmNos.length ;
265 clmKeys = format.getClmKeys();
266
267 CheckColumnData checkClass = new CheckColumnData( clmNos,clmKeys,getResource() );
268
269 ArrayDataModel nullData = new ArrayDataModel( names );
270 int[] nullClmNos = nullData.getColumnNos( nullCheck ); // バインド変数のアドレス求め
271
272 // 3.8.0.2 (2005/06/30) nullチェãƒ?‚¯確èª?
273 // int[] nullClmNos = getColumnNos( names, nullCheck ); // バインド変数のアドレス求め
274 int nullClmNosLen = nullClmNos.length ;
275
276 int executeCount = 0;
277 int commitCount = 0;
278 char sep = separator.charAt(0);
279 boolean errFlag = true;
280 // Connection conn = null;
281 Transaction tran = null; // 5.1.9.0 (2010/08/01) Transaction 対å¿?
282 PreparedStatement pstmt = null ;
283 String[] data = null ;
284 int skip = skipRowCount; // 5.5.7.1 (2012/10/05)
285 try {
286 // 5.1.9.0 (2010/08/01) Transaction 対å¿?
287 TransactionTag tranTag = (TransactionTag)findAncestorWithClass( this,TransactionTag.class );
288 if( tranTag == null ) {
289 // tran = new TransactionReal( dbid,getApplicationInfo() );
290 tran = new TransactionReal( getApplicationInfo() ); // 5.3.7.0 (2011/07/01) 引数変更
291 }
292 else {
293 tran = tranTag.getTransaction();
294 }
295 // conn = ConnectionFactory.connection( dbid,getApplicationInfo() ); // 3.8.7.0 (2006/12/15)
296
297 // try {
298 Connection conn = tran.getConnection( dbid ); // 5.1.9.0 (2010/08/01) Transaction 対å¿?
299 pstmt = conn.prepareStatement( sql );
300 String line ;
301 while((line = reader.readLine()) != null) {
302 if( line.length() == 0 || line.charAt( 0 ) == '#' ) { continue; }
303 else if( skip > 0 ){ skip--; continue;} // 5.5.7.1 (2012/10/05)
304 else {
305 // 5.2.2.0 (2010/11/01) ""で囲われてã�?‚‹ãƒ??タに改行が入ってã�?�Ÿ場合ã?対å¿?
306 int quotCount = StringUtil.countChar( line, '"' );
307 if( quotCount % 2 != 0 ) {
308 String addLine = null;
309 StringBuilder buf = new StringBuilder( line );
310 while(quotCount % 2 != 0 && (addLine = reader.readLine()) != null) {
311 if( line.length() == 0 || line.charAt( 0 ) == '#' ) { continue; }
312 buf.append( HybsSystem.CR ).append( addLine );
313 quotCount += StringUtil.countChar( addLine, '"' );
314 }
315 line = buf.toString();
316 }
317
318 // 3.8.5.1 (2006/05/08) 取込ãƒ??タã�?name 列より少なã�??合ã?対応を追åŠ?
319 data = StringUtil.csv2Array( line , sep , nameLen );
320
321 // 3.6.0.2 (2004/10/04) カラãƒ?¤‰換
322 if( useColumnAdjust ) {
323 data = checkClass.adjustData( data );
324 }
325
326 // 3.6.0.2 (2004/10/04) カラãƒ?ƒ�ェãƒ?‚¯
327 if( useColumnCheck ) {
328 ErrorMessage errMsg = checkClass.checkData( executeCount, data );
329 if( !errMsg.isOK() ) {
330 // conn.rollback();
331 tran.rollback(); // 5.1.9.0 (2010/08/01) Transaction 対å¿?
332 jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg,getResource() ) );
333 return commitCount;
334 }
335 }
336
337 // 3.8.0.2 (2005/06/30) nullチェãƒ?‚¯確èª?
338 if( nullClmNosLen > 0 ) {
339 ErrorMessage errMsg = new ErrorMessage( "Null Check Columns Error!" );
340
341 for( int i=0; i<nullClmNosLen; i++ ) {
342 int clm = nullClmNos[i];
343 if( data[clm] == null || data[clm].length() == 0 ) {
344 String label = getResource().getLabel( nullCheck[i] );
345 // ERR0012 : æŒ?®šã?ãƒ??タがセãƒ?ƒˆされてã�?�¾せんã€?NULLエラー)。key={0}
346 errMsg.addMessage( executeCount+1,ErrorMessage.NG,"ERR0012",label );
347 }
348 }
349 if( !errMsg.isOK() ) {
350 // conn.rollback();
351 tran.rollback(); // 5.1.9.0 (2010/08/01) Transaction 対å¿?
352 jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg,getResource() ) );
353 return commitCount;
354 }
355 }
356
357 for( int i=0; i<clmNosLen; i++ ) {
358 String val = data[clmNos[i]];
359 if( val != null && val.startsWith( "'0" ) ) {
360 val = val.substring( 1 );
361 }
362 // pstmt.setObject( i+1,val ); // 5.3.8.0 (2011/08/01) 処ç�??簡ç´?Œ–
363 pstmt.setString( i+1,val );
364 }
365
366 pstmt.execute();
367 if( commitBatch > 0 && ( executeCount%commitBatch == 0 ) ) {
368 // conn.commit();
369 tran.commit(); // 5.1.9.0 (2010/08/01) Transaction 対å¿?
370 commitCount = executeCount;
371 }
372 executeCount++ ;
373 }
374 }
375 // conn.commit();
376 tran.commit(); // 5.1.9.0 (2010/08/01) Transaction 対å¿?
377 commitCount = executeCount ;
378 errFlag = false; // エラーではなã�?
379 // }
380 // finally {
381 // Closer.stmtClose( pstmt );
382 // }
383 }
384 catch (IOException ex) {
385 String errMsg = "ファイル読込みエラー[" + reader.toString() + "]"
386 + " 行番号=[" + executeCount +"]"
387 + " 登録件数=[" + commitCount + "]" ;
388 throw new HybsSystemException( errMsg,ex );
389 }
390 catch (SQLException ex) {
391 String errMsg = "sql=[" + sql + "]" + HybsSystem.CR
392 + "names=[" + StringUtil.array2csv( names ) + "]" + HybsSystem.CR
393 + "vals =[" + StringUtil.array2csv( data ) + "]" + HybsSystem.CR
394 + " 行番号=[" + executeCount +"]"
395 + " 登録件数=[" + commitCount + "]" + HybsSystem.CR
396 + " errorCode=[" + ex.getErrorCode() + "] State=[" +
397 ex.getSQLState() + "]" + HybsSystem.CR ;
398 throw new HybsSystemException( errMsg,ex );
399 }
400 finally {
401 Closer.stmtClose( pstmt );
402 // tran.close( errFlag ); // 5.1.9.0 (2010/08/01) Transaction 対å¿?
403 if( tran != null ) { // 5.5.2.6 (2012/05/25) findbugs対å¿?
404 tran.close( errFlag ); // 5.1.9.0 (2010/08/01) Transaction 対å¿?
405 }
406 // if( errFlag ) { ConnectionFactory.remove( conn,dbid ); } // 削除
407 // else { ConnectionFactory.close( conn,dbid ); } // 返却
408 // conn = null;
409 }
410
411 return commitCount;
412 }
413
414 /**
415 * BufferedReader よりã€?NAME 行ã?é ?›®名情報を読み取りますã?
416 * ãƒ??タカラãƒ?‚ˆり前にã€??目名情報を示ã�?"#Name" が存在する仮定で取り込みますã?
417 * こã?行ã?、ファイルの形式に無関係に、TAB で区åˆ?‚‰れてã�?�¾すã?
418 * #NAME 配å?の先é?(行番号にあたるå?æ‰?は、ROW_NO とã�?�†キーを割り当てますã?
419 * columns が設定されてã�?‚‹場合ã?ã€?NAME 行ではなくã?columns を優先しますã?
420 *
421 * @og.rev 3.6.0.0 (2004/09/22) #NAME 行が見つからなã�??合ã?、エラーとしますã?
422 * @og.rev 3.6.0.2 (2004/10/04) columns が設定されてã�?‚‹場合ã?、それを返しますã?
423 *
424 * @param reader PrintWriterオブジェクãƒ?
425 *
426 * @return カラãƒ?��配å?
427 */
428 private String[] readName( final BufferedReader reader ) {
429 if( columns != null && columns.length > 0 ) {
430 return columns ;
431 }
432
433 try {
434 String line;
435 while((line = reader.readLine()) != null) {
436 if( line.length() == 0 ) { continue; }
437 if( line.charAt(0) == '#' ) {
438 if( line.length() >= 5 &&
439 "#NAME".equalsIgnoreCase( line.substring( 0,5 ) ) ) {
440 String[] rtn = StringUtil.csv2Array( line ,TAB_SEPARATOR.charAt(0) );
441 rtn[0] = "ROW_NO"; // 先é?カラãƒ?�«カラãƒ?��を与えるã?
442 return rtn ;
443 }
444 else { continue; }
445 }
446 else {
447 String errMsg = "#NAME が見つかる前にãƒ??タが見つかりましたã€? + HybsSystem.CR
448 + " LINE=" + line; // 5.1.8.0 (2010/07/01) errMsg 修正
449 throw new HybsSystemException( errMsg );
450 }
451 }
452 }
453 catch (IOException ex) {
454 String errMsg = "ファイル読込みエラー[" + reader.toString() + "]" ;
455 throw new HybsSystemException( errMsg,ex );
456 }
457
458 String errMsg = "#NAME が見つかりませんでしたã€?;
459 throw new HybsSystemException( errMsg );
460 }
461
462 /**
463 * SQLにバインドされる変数のファイルに対するアドレスの配å?を返しますã?
464 *
465 * @og.rev 3.6.0.2 (2004/10/04) 処ç�?ƒジãƒ?‚¯変更
466 * @og.rev 3.8.0.2 (2005/06/30) clms の null時対å¿?
467 *
468 * @param names ファイルヘッãƒ??の名称配å?
469 * @param clms SQLにバインドされる名称のCSVæ–?—å?
470 *
471 * @return int[] SQLにバインドされる変数のファイルに対するアドレスの配å?
472 */
473 // private int[] getColumnNos( final String[] names,final String[] clms ) {
474 // int[] clmNos = new int[0];
475 //
476 // if( clms != null ) {
477 // clmNos = new int[clms.length];
478 // for( int i=0; i<clms.length; i++ ) {
479 // boolean flag = true;
480 // for( int j=0; flag && j<names.length; j++ ) {
481 // if( clms[i].equalsIgnoreCase( names[j] ) ) {
482 // clmNos[i] = j;
483 // flag = false;
484 // }
485 // }
486 // // 見つからなã�??合ã?エラー
487 // if( flag ) {
488 // String errMsg = "æŒ?®šã?カラãƒ?��は、ファイルのカラãƒ??にä¸??しませんã€?
489 // + " カラãƒ?[" + clms[i] + "]"
490 // + " カラãƒ??=[" + StringUtil.array2csv( names ) + "]" ;
491 // throw new HybsSystemException( errMsg );
492 // }
493 // }
494 // }
495 // return clmNos;
496 // }
497
498 /**
499 * BufferedReader を取得しますã?
500 *
501 * ここでは、ä¸?ˆ¬çš?�ªファイル出力をè€??した BufferedReader を作æ?しますã?
502 *
503 * @return æŒ?®šã?読み取り用BufferedReaderオブジェクãƒ?
504 */
505 private BufferedReader getBufferedReader() {
506 if( filename == null ) {
507 String errMsg = "ファイル名がセãƒ?ƒˆされてã�?�¾せんã€?;
508 throw new HybsSystemException( errMsg );
509 }
510 String directory = HybsSystem.url2dir( fileURL );
511 File file = new File( StringUtil.urlAppend( directory,filename ) );
512
513 BufferedReader out = FileUtil.getBufferedReader( file,encode );
514
515 return out ;
516 }
517
518 /**
519 * フォーマットをセãƒ?ƒˆしますã?
520 * UPDATE GExx SET CLMA = [CLMA] WHERE KEY1 = [KEY1] 形式よりã?
521 * [CLMA]、[KEY1] をé?に、clmKeys 配å?に格納しますã?
522 * またã?入力フォーマットã?は、[カラãƒ?��]の個所ã‚?? に置き換えた
523 * 値をã?返しますã?こã?SQLæ–??、そのまま PreparedStatement に渡しますã?
524 * 先ã?SQLæ–?�ªらã?UPDATE GExx SET CLMA = ? WHERE KEY1 = ? に、変換しますã?
525 *
526 * @og.rev 3.6.0.2 (2004/10/04) 新規追åŠ?
527 *
528 * @param fmt [カラãƒ?��] 形式ã?フォーマットデータ
529 *
530 * @return [カラãƒ?��] ã‚?? に置き換えたæ–?—å?
531 */
532 // private String makeFormat( final String fmt ) {
533 // StringBuilder buf = new StringBuilder( fmt.length() );
534 //
535 // String fmt2 = fmt.replace( '[',']' );
536 // CSVTokenizer token = new CSVTokenizer( fmt2,']',false );
537 // int count = token.countTokens() / 2 ;
538 // clmKeys = new String[ count ];
539 //
540 //// String format = null;
541 // for( int i=0; i<count; i++ ) {
542 //// format = token.nextToken();
543 //// buf.append( format);
544 // buf.append( token.nextToken() ); // format
545 // clmKeys[i] = token.nextToken();
546 // buf.append( "?" ); // [カラãƒ? ã‚?? に置き換ã�?
547 // }
548 //// format = token.nextToken();
549 //// buf.append( format );
550 // buf.append( token.nextToken() ); // format
551 //
552 // return buf.toString();
553 // }
554
555 /**
556 * 【TAGã€?通常は使ã�?�¾せん)検索時ã?DB接続IDを指定しまã�?初期値:DEFAULT)ã€?
557 *
558 * @og.tag
559 * 検索時ã?DB接続IDを指定しますã?初期値は、DEFAULT ですã?
560 *
561 * @param id ãƒ??タベã?ス接続ID
562 */
563 public void setDbid( final String id ) {
564 dbid = nval( getRequestParameter( id ),dbid );
565 }
566
567 /**
568 * 【TAG】可変長ファイルを作æ?するときã?é ?›®区åˆ?‚Šæ–?—をセãƒ?ƒˆしまã�?初期値:タãƒ?ã€?
569 *
570 * @og.tag 可変長ファイルを作æ?するときã?é ?›®区åˆ?‚Šæ–?—をセãƒ?ƒˆしますã?
571 *
572 * @param separator é ?›®区åˆ?‚Šæ–??
573 */
574 public void setSeparator( final String separator ) {
575 this.separator = nval( getRequestParameter( separator ),this.separator );
576 }
577
578 /**
579 * 【TAG】読み取りå…?ƒ‡ィレクトリ名をæŒ?®šしまã�?
580 * (初期値:FILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])ã€?
581 *
582 * @og.tag
583 * こã?属æ?でæŒ?®šされるãƒ?‚£レクトリより、ファイルを読み取りますã?
584 * æŒ?®š方法ã?ã€??常の fileURL 属æ?と同様に、å?頭がã?'/' (UNIX) またã?ã€?¼’文字目がã?
585 * ":" (Windows)の場合ã?、指定ã?URLそã?ままのãƒ?‚£レクトリに、そã�?�§なã�??合ã?ã€?
586 * fileURL = "{@USER.ID}" とæŒ?®šすると、FILE_URL 属æ?でæŒ?®šã?フォルãƒ??下にã€?
587 * さらに、各個人ID別のフォルãƒ??下よりã?読み取りますã?
588 * (初期値:シスãƒ?ƒ 定数のFILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])ã€?
589 *
590 * @og.rev 4.0.0.0 (2005/01/31) StringUtil.urlAppend メソãƒ?ƒ‰の利用
591 * @og.rev 4.0.0.0 (2007/11/20) æŒ?®šされたãƒ?‚£レクトリ名ã?æœ?¾Œが"\"or"/"で終わってã�?�ªã�??合にã€?/"を付加するã€?
592 *
593 * @param url ファイルURL
594 * @see org.opengion.hayabusa.common.SystemData#FILE_URL
595 */
596 public void setFileURL( final String url ) {
597 String furl = nval( getRequestParameter( url ),null );
598 if( furl != null ) {
599 char ch = furl.charAt( furl.length()-1 );
600 if( ch != '/' && ch != '\\' ) { furl = furl + "/"; }
601 fileURL = StringUtil.urlAppend( fileURL,furl );
602 }
603 }
604
605 /**
606 * 【TAG】ファイルを作æ?するときã?ファイル名をセãƒ?ƒˆしまã�?
607 * (初期値:FILE_FILENAME[={@og.value org.opengion.hayabusa.common.SystemData#FILE_FILENAME}])ã€?
608 *
609 * @og.tag
610 * ファイルを作æ?するときã?ファイル名をセãƒ?ƒˆしますã?
611 * (初期値:シスãƒ?ƒ 定数のFILE_FILENAME[={@og.value org.opengion.hayabusa.common.SystemData#FILE_FILENAME}])ã€?
612 *
613 * @param filename ファイルå�?
614 * @see org.opengion.hayabusa.common.SystemData#FILE_FILENAME
615 */
616 public void setFilename( final String filename ) {
617 this.filename = nval( getRequestParameter( filename ),this.filename );
618 }
619
620 /**
621 * 【TAG】ファイルを作æ?するときã?ファイルエンコーãƒ?‚£ング名をセãƒ?ƒˆしまã�?
622 * (初期値:FILE_ENCODE[={@og.value org.opengion.hayabusa.common.SystemData#FILE_ENCODE}])ã€?
623 *
624 * @og.tag
625 * 初期値は、シスãƒ?ƒ パラメータ の FILE_ENCODE 属æ?で、設定してã�?�¾すã?
626 * Shift_JIS,MS932,Windows-31J,UTF-8,ISO-8859-1,UnicodeLittle?¥?¥?¥
627 * (初期値:シスãƒ?ƒ 定数のFILE_ENCODE[={@og.value org.opengion.hayabusa.common.SystemData#FILE_ENCODE}])ã€?
628 *
629 * @param enc ファイルエンコーãƒ?‚£ングå�?
630 * @see <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a>
631 * @see org.opengion.hayabusa.common.SystemData#FILE_ENCODE
632 */
633 public void setEncode( final String enc ) {
634 encode = nval( getRequestParameter( enc ),encode );
635 }
636
637 /**
638 * 【TAG】query の結果を画面上に表示するメãƒ?‚»ージIDを指定しまã�?初期値:MSG0040[ã€?»¶登録しました])ã€?
639 *
640 * @og.tag
641 * ここでは、検索結果の件数ã‚?™»録された件数をまずå?力しã€?
642 * そã?次に、ここでæŒ?®šしたメãƒ?‚»ージをリソースから取得して
643 * 表示しますã?
644 * 表示させたくなã�??合ã?, displayMsg = "" をセãƒ?ƒˆしてくださいã€?
645 * 初期値は、検索件数を表示しますã?
646 * ※ こã?属æ?には、リクエスト変数({@XXXX})は使用できませんã€?
647 *
648 * @param id ãƒ?‚£スプレイに表示させるメãƒ?‚»ージ ID
649 */
650 public void setDisplayMsg( final String id ) {
651 if( id != null ) { displayMsg = id; }
652 }
653
654 /**
655 * 【TAGã€?NAME 属æ?の代わりとなるファイルのカラãƒ?��ã‚?CSV形式でæŒ?®šしますã?
656 *
657 * @og.tag
658 * ãƒ??タファイルの先é?行にã€?NAME 行があり、読み取るべきファイルの
659 * カラãƒ?��が記述されてã�?�¾すã?通常は、このカラãƒ?��を取り込んでã€?
660 * å�?ƒ‡ータ列ã?カラãƒ?‚’æŒ?®šしますã?
661 * こã?属æ?は、ファイルに#NAME 行が存在しなã�?他シスãƒ?ƒ からの入力ファイルç?
662 * 場合にã€?NAME 属æ?の代わりに、カラãƒ?��を外部よりæŒ?®šしますã?
663 *
664 * @og.rev 3.8.5.1 (2006/05/08) getCSVParameter の使用を中止
665 *
666 * @param clms ファイルのカラãƒ?��(カンマ区åˆ?‚Šæ–??
667 */
668 public void setColumns( final String clms ) {
669 columns = StringUtil.csv2Array( nval( getRequestParameter( clms ),null ),',' );
670 }
671
672 /**
673 * 【TAG】指定数毎にコミットを発行しまã�?初期値:0 終äº?�¾でコミットしません)ã€?
674 *
675 * @og.tag
676 * 通常は、å?ての処ç�?�Œ正常に終äº?�™るか、なにもしなã�?�‹(トランザクション)
677 * を判断すべきでã€??中でのコミットã?しませんã€?
678 * しかしã?場合によって、件数が異常に多い場合や、å?実行可能な場合ã?ã€?
679 * 途中でコミットしてã€??度、å?ç�?�§きるもã?ã�?�‘をå?ç�?�—てしまã�?�¨ã�?�†方法がありますã?
680 * またã?ロールバックエリアの関係などで、データ量が多い場合に、å?ç�?™‚間が異常に
681 * 長くなる事があり、指定件数ごとのコミット機è?を用意してã�?�¾すã?
682 * 0 に設定すると、終äº?�¾でコミットしません。å?期å?はã€? ですã?
683 *
684 * @param cmtBat æŒ?®š数毎にコミットを発è¡?初期値:0)
685 */
686 public void setCommitBatch( final String cmtBat ) {
687 commitBatch = nval( getRequestParameter( cmtBat ),commitBatch );
688 }
689
690 /**
691 * 【TAG】カラãƒ?ƒ�ェãƒ?‚¯(DBTypeチェãƒ?‚¯)を行うかどã�?�‹を設定しまã�?初期値:false)ã€?
692 *
693 * @og.tag
694 * カラãƒ??整合æ?チェãƒ?‚¯を行う場合ã?こã?属æ?を設å®?true)しますã?
695 * 初期値は、行わなã�?false)ですã?
696 * チェãƒ?‚¯するカラãƒ??ã€?NAME ã‚?columns でæŒ?®šされたカラãƒ?�§はなくã?
697 * BODY部のSQLæ–?�§æŒ?®šされたカラãƒ?��( [カラãƒ?��] )ですã?これは、直接、SQLæ–?¸に
698 * 記述してã�?‚‹値ã‚??{@XXXX}æ–?—等ã?、チェãƒ?‚¯出来なã�?‚ºですã?
699 *
700 * @og.rev 3.6.0.2 (2004/10/04) 新規追åŠ?取り込み時å?チェãƒ?‚¯
701 *
702 * @param flag チェãƒ?‚¯を行うかどã�?�‹(true:行う/false:行わなã�?
703 * @see #setUseColumnAdjust( String )
704 */
705 public void setUseColumnCheck( final String flag ) {
706 useColumnCheck = nval( getRequestParameter( flag ),useColumnCheck );
707 }
708
709 /**
710 * 【TAG】カラãƒ?¤‰換(DBType変換)を行うかどã�?�‹を設定しまã�?初期値:false)ã€?
711 *
712 * @og.tag
713 * カラãƒ??変換を行う場合ã?こã?属æ?を設å®?true)しますã?
714 * 初期値は、行わなã�?false)ですã?
715 * 変換するカラãƒ??ã€?NAME ã‚?columns でæŒ?®šされたカラãƒ?�§はなくã?
716 * BODY部のSQLæ–?�§æŒ?®šされたカラãƒ?��[カラãƒ?��]ですã?これは、直接、SQLæ–?¸に
717 * 記述してã�?‚‹値ã‚??{@XXXX}æ–?—等ã?、変換出来なã�?‚ºですã?
718 *
719 * @og.rev 3.6.0.2 (2004/10/04) 新規追åŠ?取り込み時変換
720 *
721 * @param flag 変換を行うかどã�?�‹(true:行う/false:行わなã�?
722 * @see #setUseColumnCheck( String )
723 */
724 public void setUseColumnAdjust( final String flag ) {
725 useColumnAdjust = nval( getRequestParameter( flag ),useColumnAdjust );
726 }
727
728 /**
729 * 【TAG】NULL チェãƒ?‚¯すべきカラãƒ??をカンマ区åˆ?‚Š(CSV形å¼?でæŒ?®šしますã?
730 *
731 * @og.tag nullCheck="AAA,BBB,CCC,DDD"
732 * <del>先に配å?にåˆ?§£してからリクエスト変数の値を取得するよã�?�«しますã?
733 * こうする事で、リクエストにカンマ区åˆ?‚Šの値を設定できるようになりますã?</del>
734 * åˆ?§£方法ã?ã€??常のパラメータ取得後に、CSVåˆ?§£しますã?
735 *
736 * @og.rev 3.8.0.2 (2005/06/30) 新規追åŠ?
737 * @og.rev 3.8.8.5 (2007/03/09) 通常のパラメータ取得後に、CSVåˆ?§£に戻しますã?
738 *
739 * @param clms カラãƒ??(CSV形å¼?
740 */
741 public void setNullCheck( final String clms ) {
742 nullCheck = StringUtil.csv2Array( getRequestParameter( clms ) );
743 if( nullCheck.length == 0 ) { nullCheck = null; }
744 }
745
746 /**
747 * 【TAG】取り込み時に除外する行をæŒ?®šしまã�?初期値:0)ã€?
748 *
749 * @og.tag
750 * TAB区åˆ?‚Šãƒ?‚ストやEXCEL等ã?ãƒ??タの読み始めの初期値を指定しますã?
751 * ファイルの先é?行がã€?¼�行としてカウントしますã?で、設定å?は、読み飛ã?ã�?
752 * 件数になりますã?(?‘とæŒ?®šするとã€?¼‘件読み飛ã?しã??’行目から読み込みますã?)
753 * 読み飛ã?しã?、コメント行などは、無視しますã?で、実際の行数åˆ?ªみ飛ã?しますã?
754 * ?ƒNAME属æ?ã‚??columns 属æ?は、有効ですã?
755 *
756 * @og.rev 5.5.7.1 (2012/10/05) 新規追åŠ?
757 *
758 * @param count 先é?行を無視するかどã�?�‹(true:無視すã‚?false:無視しなã�?
759 */
760 public void setSkipRowCount( final String count ) {
761 skipRowCount = nval( getRequestParameter( count ),skipRowCount );
762 }
763
764 /**
765 * カラãƒ?¤‰換、カラãƒ?ƒ�ェãƒ?‚¯を行うå†?ƒ¨クラス
766 *
767 * @og.rev 4.0.0.0 (2005/01/31) static クラス化ã?引数にResourceManager追åŠ?
768 * @og.group ファイル入åŠ?
769 *
770 * @version 4.0
771 * @author Kazuhiko Hasegawa
772 * @since JDK5.0,
773 */
774 static class CheckColumnData {
775 private final DBColumn[] dbClm ;
776 private final int[] clmChkNo ;
777 private final int len ; // 長さ0ã?時ã?、なにもしなã�??
778 private final ErrorMessage errMsg = new ErrorMessage( "Check Columns Error!" );
779
780 /**
781 * コンストラクター
782 *
783 * @param clmNo カラãƒ?•ª号配å?
784 * @param chkClm String[]
785 * @param resource ResourceManager
786 */
787 CheckColumnData( final int[] clmNo, final String[] chkClm,final ResourceManager resource ) {
788 if( clmNo == null || clmNo.length == 0 ||
789 chkClm == null || chkClm.length == 0 ) { // return; } // 何もしなã�?
790
791 dbClm = null;
792 clmChkNo = null;
793 len = 0;
794 }
795 else {
796 clmChkNo = clmNo ;
797 len = clmNo.length ;
798 dbClm = new DBColumn[len];
799 for( int i=0; i<len; i++ ) {
800 dbClm[i] = resource.makeDBColumn( chkClm[i] ); // 4.0.0 (2005/01/31)
801 }
802 }
803 }
804
805 /**
806 * 引数のãƒ??タã‚?DBColumn で正規化(valueSetメソãƒ?ƒ‰経由)しますã?
807 *
808 * @param data ?‘行å?のãƒ??タ配å?
809 * @return String[]
810 * @see org.opengion.hayabusa.db.DBColumn#valueSet( String )
811 */
812 String[] adjustData( final String[] data ) {
813 if( len == 0 ) { return data; }
814 String[] ajstData = new String[len];
815 for( int i=0; i<len; i++ ) {
816 String val = data[clmChkNo[i]];
817 ajstData[i] = dbClm[i].valueSet( val );
818 }
819 return ajstData ;
820 }
821
822 /**
823 * 引数のãƒ??タã‚?DBColumn で正規化(valueSetメソãƒ?ƒ‰経由)しますã?
824 *
825 * @param row 行番号
826 * @param data ?‘行å?のãƒ??タ配å?
827 * @return ErrorMessage
828 * @see org.opengion.hayabusa.db.DBColumn#valueSet( String )
829 */
830 ErrorMessage checkData( final int row,final String[] data ) {
831 for( int i=0; i<len; i++ ) {
832 String val = data[clmChkNo[i]];
833 errMsg.append( row+1,dbClm[i].valueCheck( val ) );
834 }
835 return errMsg ;
836 }
837 }
838
839 /**
840 * こã?オブジェクトã?æ–?—å?表現を返しますã?
841 * 基本çš?�«ãƒ?ƒ�ãƒ?‚°目çš?�«使用しますã?
842 *
843 * @return こã?クラスのæ–?—å?表現
844 */
845 @Override
846 public String toString() {
847 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
848 .println( "VERSION" ,VERSION )
849 .println( "dbid" ,dbid )
850 .println( "separator" ,separator )
851 .println( "fileURL" ,fileURL )
852 .println( "filename" ,filename )
853 .println( "encode" ,encode )
854 .println( "displayMsg" ,displayMsg )
855 .println( "columns" ,columns )
856 .println( "clmKeys" ,clmKeys )
857 .println( "sql" ,sql )
858 .println( "commitBatch" ,commitBatch )
859 .println( "useColumnCheck" ,useColumnCheck )
860 .println( "useColumnAdjust" ,useColumnAdjust)
861 .println( "nullCheck" ,nullCheck )
862 .println( "dyStart" ,dyStart )
863 .println( "Other..." ,getAttributes().getAttribute() )
864 .fixForm().toString() ;
865 }
866 }