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