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.common;
017
018 import org.opengion.fukurou.xml.HybsXMLSave;
019 import org.opengion.fukurou.util.Closer ;
020
021 import java.sql.Connection;
022 import java.sql.SQLException;
023
024 import java.io.Reader;
025 import java.io.BufferedReader;
026 import java.io.InputStreamReader;
027 import java.io.FileInputStream;
028 import java.io.InputStream;
029 import java.io.IOException;
030 import java.io.File;
031 import java.io.UnsupportedEncodingException;
032
033 import java.util.List;
034 import java.util.ArrayList;
035 import java.util.Enumeration;
036 import java.util.jar.JarFile;
037 import java.util.jar.JarEntry;
038 import java.net.URL;
039
040 /**
041 * ORACLE XDK 形式ã?XMLファイルを読み取って、データベã?スに登録しますã?
042 * 起å‹?実è¡?は、コンãƒ?‚スト読み取り時ã?初回のみですã?GE12パラメータを変更した
043 * 場合ã?、コンãƒ?‚ストã?リロードがå¿?¦�ですã?
044 * 登録の実行有無の判断は、ファイルの更新時刻より判断しますã?(useTimeStamp=true の場å�?
045 * これは、読み取りファイルの更新時刻がã??�でなã�??合ã?読み取りを行いますã?
046 * 読み取りが完äº?�—たå?合ã?、更新時刻ã‚???に設定しますã?
047 * 読み取るファイルは、クラスローãƒ??のリソースとして取得されますã?で、クラスパスã�?
048 * 設定されてã�?‚‹å¿?¦�がありますã?またã?ファイルは、拡張子が xml で、UTF-8でエンコーãƒ?
049 * されてã�?‚‹å¿?¦�がありますã?通常は、ファイル名がãƒ??ブル名と同ä¸?�«しておくå¿?¦�が
050 * ありますが、ROWSETのtable属æ?にãƒ??ブル名をセãƒ?ƒˆしておくことも可能ですã?
051 * ファイルの登録é ??、原å‰??クラスローãƒ??の検索é ?�«、見つかったå?てのファイルã‚?
052 * 登録しますã?ãƒ??タそã?もã?は、INSERT のみ対応してã�?�¾すã?で、原å‰?™»録é ??無視されますã?
053 * ただしã?拡張XDK 形式で、EXEC_SQL タグを使用した場合ã?、登録é ?�Œ影響する可能性がありますã?
054 * 例:GE12.xml GE12 ãƒ??ブルに登録するXMLファイル
055 * 登録時に、既存ã?ãƒ??タの破æ£?�Œå¿?¦�な場合ã?、拡張XDK 形式ã?XMLファイルã‚?
056 * 作æ?してください。これã?、EXEC_SQL タグに書き込んだSQLæ–?‚’実行しますã?
057 * 詳細は、{@link org.opengion.fukurou.xml.HybsXMLHandler HybsXMLHandler} クラスを参照してくださいã€?
058 *
059 * <ROWSET tableName="XX" >
060 * <EXEC_SQL> æœ??に記載して、å?期å?ç�?ãƒ??タクリアç?を実行させるã€?
061 * delete from GEXX where YYYYY
062 * </EXEC_SQL>
063 * <ROW num="1">
064 * <カラãƒ?>値1</カラãƒ?>
065 * ?¥?¥?¥
066 * <カラãƒ?>値n</カラãƒ?>
067 * </ROW>
068 * ?¥?¥?¥
069 * <ROW num="n">
070 * ?¥?¥?¥
071 * </ROW>
072 * <EXEC_SQL> æœ?¾Œに記載してã€??目の設å®?整合æ?登録)を行うã€?
073 * update GEXX set AA='XX' , BB='XX' where YYYYY
074 * </EXEC_SQL>
075 * <ROWSET>
076 *
077 * @og.rev 4.0.0.0 (2004/12/31) 新規作æ?
078 * @og.group 初期åŒ?
079 *
080 * @version 4.0
081 * @author Kazuhiko Hasegawa
082 * @since JDK5.0,
083 */
084 public final class InitFileLoader {
085 private final String CLASSPATH ;
086 private final Connection connection ;
087 private boolean fileCommit = false; // ファイル毎にコミットå?ç�?‚’行うかどã�?�‹(true:行う/false:行わなã�?
088
089 /**
090 * コネクションを引数にする、コンストラクターですã?
091 * classPath="resource" で初期化された InitFileLoader を作æ?しますã?
092 *
093 * @param conn 登録用コネクション
094 */
095 public InitFileLoader( final Connection conn ) {
096 this( conn,"resource" );
097 }
098
099 /**
100 * コネクションと検索パスを指定して構築するã?コンストラクターですã?
101 * 対象ファイルは、classPath でæŒ?®šされた場æ‰?‚’、クラスローãƒ??で検索しますã?
102 * ここで見つかったパス以下ã? XMLファイル(拡張子ã?小文字でã€?xml )を検索
103 * しますã?こã?ファイル名ã? ãƒ??ブルå�?xml 形式で格納しておきますã?
104 *
105 * @param conn 登録用コネクション
106 * @param classPath 対象となるファイル群を検索する、クラスパス
107 */
108 public InitFileLoader( final Connection conn,final String classPath ) {
109 connection = conn ;
110 CLASSPATH = classPath;
111 }
112
113 /**
114 * ファイル毎にコミットå?ç�?‚’行うかどã�?�‹æŒ?®šしまã�?初期値:false[行わない])ã€?
115 * 対象ファイル毎に、データベã?スへの登録を完äº?commit)するかどã�?�‹を指定しますã?
116 * 通常、Connection は、autoCommit ã‚?false に設定しã€?¼‘件ごとの処ç�??行いませんã€?
117 * さらに、XMLファイルにも相互関連があるå?合があるため、è¤?•°ファイルを取り込ã‚??合ã?ã€?
118 * それらをä¸?¾¤として処ç�?�—たいケースもありますã?またã?å�?ƒ•ァイルが独立してã�?‚‹
119 * 場合ã?、他ã?ファイル取り込み時にエラーが発生してもã?それまでのåˆ??、取り込みたい
120 * ケースがありますã?
121 * ここでは、ファイル毎にコミットを発行するかどã�?�‹を指定できますã?
122 * 初期値は、false[行わない]ですã?
123 * ※ true に設定したå?合でもã?途中でエラーが発生したå?合ã?、それ以降ã?処ç�??ã€?
124 * 継続しません。それ以前ã?処ç�?�Œ、登録されてã�?‚‹ã�?�‘ですã?
125 *
126 * @param fileCmt ファイル毎にコミットå?ç�?‚’行うかどã�?�‹ [true:行う/false:行わない]
127 */
128 public void setFileCommit( final boolean fileCmt ) {
129 fileCommit = fileCmt ;
130 }
131
132 /**
133 * 対象となるファイル群を検索しますã?
134 * 対象ファイルは、resource フォルãƒ?�« ãƒ??ブルå�?xml 形式で格納しておきますã?
135 * こã?フォルãƒ??ファイルをピãƒ?‚¯アãƒ??しますã?
136 * useTimeStamp 属æ?ã‚?true に設定すると、このファイルのタイãƒ?‚¹タンプをã€?
137 * シスãƒ?ƒ パラメータ定義(GE12) にセãƒ?ƒˆしますã?それ以降ã?こã?タイãƒ?‚¹タンプと
138 * ファイルを比è¼?�—て、変更がなければ、登録処ç�?‚’行いませんã€?
139 *
140 * @og.rev 4.0.0.0 (2007/11/28) メソãƒ?ƒ‰の戻りå?をチェãƒ?‚¯しますã?
141 * @og.rev 5.3.6.0 (2011/06/01) 実フォルãƒ??場合ã?フォルãƒ?šŽ層を下る処ç�?‚’追åŠ?
142 * @og.rev 5.5.2.6 (2012/05/25) JarFile をã?Closer#zipClose( ZipFile ) メソãƒ?ƒ‰を利用して、close しますã?
143 * @og.rev 5.6.6.1 (2013/07/12) jarファイルの場合も、タイãƒ?‚¹タンプ管ç�??対象としますã?
144 *
145 * @param useTimeStamp タイãƒ?‚¹タンプã?管ç�?‚’行うかどã�?�‹[true:行う/false:行わない]
146 */
147 public void loadInitFiles( final boolean useTimeStamp ) {
148 List<File> fileList = new ArrayList<File>();
149
150 // 5.5.2.6 (2012/05/25) findbugs対å¿?
151 JarFile jarFile = null;
152 try {
153 // System.out.println( " ==========================" );
154
155 ClassLoader loader = Thread.currentThread().getContextClassLoader();
156 Enumeration<URL> enume = loader.getResources( CLASSPATH ); // 4.3.3.6 (2008/11/15) Generics警告対å¿?
157 while( enume.hasMoreElements() ) {
158 URL url = enume.nextElement(); // 4.3.3.6 (2008/11/15) Generics警告対å¿?
159 // jar:file:/実ディレクトリ またã?、file:/実ディレクトリ
160 System.out.println( " InitFileLoader Scan:[ " + url + " ]" ); // 5.6.6.1 (2013/07/12) メãƒ?‚»ージ出åŠ?
161 String dir = url.getFile();
162 if( "jar".equals( url.getProtocol() ) ) {
163 // dir = file:/C:/webapps/gf/WEB-INF/lib/resource2.jar!/resource 形式ですã?
164 String jar = dir.substring(dir.indexOf( ':' )+1,dir.lastIndexOf( '!' ));
165 // jar = /C:/webapps/gf/WEB-INF/lib/resource2.jar 形式にåˆ?‚Š出しますã?
166
167 // 5.6.6.1 (2013/07/12) jarファイルもã?タイãƒ?‚¹タンプ管ç�??対象
168 File jarObj = new File( jar );
169 if( useTimeStamp && jarObj.lastModified() <= 0 ) { // fileObj は、jarファイルのこと
170 continue;
171 }
172
173 // JarFile jarFile = new JarFile( jar );
174 jarFile = new JarFile( jar );
175 Enumeration<JarEntry> flEnum = jarFile.entries() ; // 4.3.3.6 (2008/11/15) Generics警告対å¿?
176 while( flEnum.hasMoreElements() ) {
177 JarEntry ent = flEnum.nextElement(); // 4.3.3.6 (2008/11/15) Generics警告対å¿?
178 String file = ent.getName();
179 if( ! ent.isDirectory() && file.endsWith( ".xml" ) ) {
180 // // 5.6.6.1 (2013/07/12) jarファイルの中身のタイãƒ?‚¹タンプã?見なã�??
181 // if( ! useTimeStamp || ent.getTime() > 0 ) {
182 String table = file.substring( file.lastIndexOf('/')+1,file.lastIndexOf('.') );
183 InputStream stream = null;
184 try {
185 // System.out.println( " " + url + file );
186 System.out.println( " " + file ); // 5.6.6.1 (2013/07/12) メãƒ?‚»ージ変更
187 stream = jarFile.getInputStream( ent ) ;
188 loadXML( stream,connection,table );
189 }
190 // catch( IOException ex ) {
191 // String errMsg = "jar の XMLファイル読み取り時にエラーが発生しましたã€?
192 // + HybsSystem.CR + ex.getMessage();
193 // throw new RuntimeException( errMsg,ex );
194 // }
195 finally {
196 Closer.ioClose( stream );
197 }
198 if( fileCommit ) {
199 connection.commit();
200 }
201 // }
202 }
203 }
204 fileList.add( jarObj ); // 5.6.6.1 (2013/07/12) jarファイルもã?タイãƒ?‚¹タンプ管ç�??対象
205 Closer.zipClose( jarFile ); // 5.5.2.6 (2012/05/25) findbugs対å¿?
206 jarFile = null; // 正常終äº?™‚に、close() が2回呼ばれるのを防ぐためã?
207 }
208 else {
209 // // dir = /C:/webapps/gf/WEB-INF/classes/resource/ 形式ですã?
210 // File fileObj = new File( dir );
211 // File[] list = fileObj.listFiles();
212 // for( int i=0; i<list.length; i++ ) {
213 // String file = list[i].getName() ;
214 // if( list[i].isFile() && file.endsWith( ".xml" ) ) {
215 // if( ! useTimeStamp || list[i].lastModified() > 0 ) {
216 // String table = file.substring( file.lastIndexOf('/')+1,file.lastIndexOf('.') );
217 // InputStream stream = null;
218 // try {
219 // stream = new FileInputStream( list[i] ) ;
220 // System.out.println( " " + url + file );
221 // loadXML( stream,connection,table );
222 // }
223 // catch( IOException ex ) {
224 // String errMsg = "dir の XMLファイル読み取り時にエラーが発生しましたã€?
225 // + HybsSystem.CR + ex.getMessage();
226 // throw new RuntimeException( errMsg,ex );
227 // }
228 // finally {
229 // Closer.ioClose( stream );
230 // }
231 // if( fileCommit ) {
232 // connection.commit();
233 // if( !list[i].setLastModified( 0L ) ) {
234 // String errMsg = "タイãƒ?‚¹タンプã?書き換えに失敗しましたã€?
235 // + "file=" + file ; // 5.1.8.0 (2010/07/01) errMsg 修正
236 // System.out.println( errMsg );
237 // }
238 // }
239 // else {
240 // fileList.add( list[i] );
241 // }
242 // }
243 // }
244 // }
245 // 5.3.6.0 (2011/06/01) 実フォルãƒ??場合ã?フォルãƒ?šŽ層を下る処ç�?‚’追åŠ?
246 // dir = /C:/webapps/gf/WEB-INF/classes/resource/ 形式ですã?
247 File fileObj = new File( dir );
248 loadXMLDir( fileObj,useTimeStamp,fileList );
249 }
250 }
251 connection.commit();
252 // System.out.println( " ==========================" );
253 }
254 catch( SQLException ex ) {
255 String errMsg = "SQL実行時にエラーが発生しましたã€?
256 + HybsSystem.CR + ex.getMessage();
257 Closer.rollback( connection );
258 // if( connection != null ) {
259 // Closer.rollback( connection );
260 // try { connection.rollback(); }
261 // catch( SQLException ex2 ) { errMsg += ex2.getMessage(); }
262 // }
263 throw new RuntimeException( errMsg,ex );
264 }
265 catch( IOException ex ) {
266 String errMsg = "XMLファイル読み取り時にエラーが発生しましたã€?
267 + HybsSystem.CR + ex.getMessage();
268 throw new RuntimeException( errMsg,ex );
269 }
270 finally {
271 Closer.zipClose( jarFile ); // 5.5.2.6 (2012/05/25) findbugs対å¿?
272
273 // 5.3.6.0 (2011/06/01) finally 処ç�?�§、タイãƒ?‚¹タンプã?書き換えを行うã€?
274
275 // commit がæ?功したå?合ã?み、ファイルのタイãƒ?‚¹タンプã?書き換えを行うã€?
276 // if( ! fileCommit ) {
277 // File[] files = fileList.toArray( new File[fileList.size()] );
278 // for( int i=0; i<files.length; i++ ) {
279 // 5.6.6.1 (2013/07/12) useTimeStamp=true の場合ã?み、書き換えますã?
280 if( useTimeStamp ) {
281 for( File file : fileList ) {
282 if( !file.setLastModified( 0L ) ) {
283 String errMsg = "タイãƒ?‚¹タンプã?書き換えに失敗しましたã€?
284 + "file=" + file ; // 5.1.8.0 (2010/07/01) errMsg 修正
285 System.out.println( errMsg );
286 }
287 }
288 }
289 }
290 }
291
292 /**
293 * XMLフォルãƒ?ファイルを読み取り、データベã?スに追åŠ?INSERT)するメソãƒ?ƒ‰をコールしますã?
294 *
295 * ここでは、フォルãƒ?šŽ層を下るための再起処ç�?‚’行ってã�?�¾すã?
296 * XMLファイルは、ORACLE XDK拡張ファイルですã?ãƒ??ブル名をæŒ?®šすることでã€?
297 * XMLファイルをデータベã?スに登録することが可能ですã?
298 * ORACLE XDK拡張ファイルã‚??EXEC_SQLタグなどの詳細は、{@link org.opengion.fukurou.xml.HybsXMLSave}
299 * を参照願いますã?
300 *
301 * @og.rev 5.3.6.0 (2011/06/01) 実フォルãƒ??場合ã?フォルãƒ?šŽ層を下る処ç�?‚’追åŠ?
302 *
303 * @param fileObj 読取å?のファイルオブジェクãƒ?
304 * @param useTimeStamp タイãƒ?‚¹タンプã?管ç�?‚’行うかどã�?�‹[true:行う/false:行わない]
305 * @param fileList 処ç�?�—たファイルを保管しておくListオブジェクãƒ?
306 * @throws SQLException,IOException ãƒ??タベã?スアクセスエラー、またã?、データ入出力エラー
307 */
308 private void loadXMLDir( final File fileObj , final boolean useTimeStamp , final List<File> fileList )
309 throws SQLException,IOException {
310 // dir = /C:/webapps/gf/WEB-INF/classes/resource/ 形式ですã?
311 File[] list = fileObj.listFiles();
312 // Arrays.sort( list );
313 for( int i=0; i<list.length; i++ ) {
314 String file = list[i].getName() ;
315 if( list[i].isFile() && file.endsWith( ".xml" ) ) {
316 if( ! useTimeStamp || list[i].lastModified() > 0 ) {
317 String table = file.substring( file.lastIndexOf('/')+1,file.lastIndexOf('.') );
318 InputStream stream = null;
319 try {
320 System.out.println( " " + list[i] );
321 stream = new FileInputStream( list[i] ) ;
322 loadXML( stream,connection,table );
323 }
324 // catch( IOException ex ) {
325 // String errMsg = "dir の XMLファイル読み取り時にエラーが発生しましたã€?
326 // + HybsSystem.CR + ex.getMessage();
327 // throw new RuntimeException( errMsg,ex );
328 // }
329 finally {
330 Closer.ioClose( stream );
331 }
332 if( fileCommit ) {
333 connection.commit();
334 }
335 fileList.add( list[i] );
336 }
337 }
338 else {
339 loadXMLDir( list[i],useTimeStamp,fileList );
340 }
341 }
342 }
343
344 /**
345 * XMLファイルを読み取り、データベã?スに追åŠ?INSERT)しますã?
346 *
347 * XMLファイルは、ORACLE XDK拡張ファイルですã?ãƒ??ブル名をæŒ?®šすることでã€?
348 * XMLファイルをデータベã?スに登録することが可能ですã?
349 * ORACLE XDK拡張ファイルã‚??EXEC_SQLタグなどの詳細は、{@link org.opengion.fukurou.xml.HybsXMLSave}
350 * を参照願いますã?
351 *
352 * @param stream 読み取るストリーãƒ?
353 * @param conn DB接続ã?コネクション
354 * @param table 追åŠ?�™るテーブルå�?
355 *
356 * @og.rev 5.6.6.1 (2013/07/12) 更新カウント数も取得しますã?
357 * @og.rev 5.6.7.0 (2013/07/27) HybsXMLSave の DDL?ˆデータ定義è¨?ªž:Data Definition Language?‰ã?処ç�?»¶数追åŠ?
358 * @og.rev 5.6.9.2 (2013/10/18) EXEC_SQL のエラー時に Exception を発行しなã�??
359 *
360 * @return 追åŠ?�•れた件数
361 * @see org.opengion.fukurou.xml.HybsXMLSave
362 */
363 private int loadXML( final InputStream stream, final Connection conn,final String table )
364 throws SQLException,UnsupportedEncodingException {
365
366 // InputStream より、XMLファイルを読み取り、table に追åŠ?INSERT)しますã?
367 Reader reader = new BufferedReader( new InputStreamReader( stream,"UTF-8" ) );
368 HybsXMLSave save = new HybsXMLSave( conn,table );
369 save.onExecErrException( false ); // 5.6.9.2 (2013/10/18) EXEC_SQL のエラー時に Exception を発行しなã�??
370 save.insertXML( reader );
371 int insCnt = save.getInsertCount();
372 int delCnt = save.getDeleteCount();
373 int updCnt = save.getUpdateCount(); // 5.6.6.1 (2013/07/12) 更新カウント数も取å¾?
374 int ddlCnt = save.getDDLCount(); // 5.6.7.0 (2013/07/27) DDL処ç�?»¶数追åŠ?
375 String tableName = save.getTableName() ;
376
377 // System.out.println( " TABLE=[" + tableName + "] DELETE=["+ delCnt +"] INSERT=[" + insCnt + "]" );
378 // System.out.println( " TABLE=[" + tableName + "] DELETE=["+ delCnt +"] INSERT=[" + insCnt + "] UPDATE=[" + updCnt + "]" );
379 System.out.println( " TABLE=[" + tableName + "] DELETE=["+ delCnt +"] INSERT=[" + insCnt + "] UPDATE=[" + updCnt + "] DDL=[" + ddlCnt + "]" );
380 return insCnt;
381 }
382 }