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    }