001/*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016package org.opengion.hayabusa.common;
017
018import java.io.BufferedReader;
019import java.io.File;
020import java.io.InputStream;
021import java.io.InputStreamReader;
022import java.io.PrintWriter;
023import java.io.Reader;
024import java.io.UnsupportedEncodingException;
025import java.sql.Connection;
026import java.sql.PreparedStatement;
027import java.sql.ResultSet;
028import java.sql.SQLException;
029import java.sql.Statement;
030import java.util.ArrayList;
031import java.util.List;
032import java.util.Locale;
033
034import org.opengion.fukurou.util.Closer;
035import org.opengion.fukurou.util.FileUtil;
036import org.opengion.fukurou.util.StringUtil;
037import org.opengion.fukurou.util.ZipFileUtil;
038import org.opengion.fukurou.xml.HybsXMLSave;
039import org.opengion.fukurou.db.DBUtil;
040
041/**
042 * システムの自動インストールと自動更新を行います。
043 *
044 * (1)初期インストール・自動更新(#autoInsUpd)
045 *   @初期自動インストールを行うには、起動時の環境変数にINSTALL_CONTEXTSが
046 *     設定されている必要があります。
047 *     この環境変数が設定されている場合、システムリソーステーブル(GE12)が存在しなければ、
048 *     エンジンがインストールされていないと判断し、自動インストールを行います。
049 *     INSTALL_CONTEXTSにge,gfが指定されている場合は、開発環境を含めたフルバージョンが
050 *     インストールされます。
051 *     geのみが指定されている場合は、コアモジュールであるgeのみがインストールされます。
052 *
053 *     インストールスクリプトは、
054 *      webapps/[CONTEXT]/db/[DBNAME]/xml/install                       DBID=DEFAULT
055 *      webapps/[CONTEXT]/db/[DBNAME]/xml/update                        DBID=DEFAULT
056 *     以下にあるXMLファイルが全て実行されます。
057 *     また、同時に
058 *      webapps/[CONTEXT]/db/common/xml/install                         DBID=DEFAULT
059 *      webapps/[CONTEXT]/db/common/xml/update                          DBID=DEFAULT
060 *      webapps/[CONTEXT]/db/resource/xml/install                       DBID=RESOURCE   (5.6.7.0 (2013/07/27) 追加)
061 *      webapps/[CONTEXT]/db/resource/xml/update                        DBID=RESOURCE   (5.6.7.0 (2013/07/27) 追加)
062 *     以下にあるデータロードスクリプトも全て実行されます。
063 *
064 *   A自動更新については、システムリソーステーブル(GE12)の更新と、各システムの更新の2つがあります。
065 *     GE12更新の判断基準は、システムID='**'に格納されているバージョン(同一のGE12を使用し
066 *     ているシステムの最大バージョン番号)がアップした場合です。
067 *     この場合に、エンジン内部で保持しているXMLファイルよりシステムリソースの再ロードを行います。
068 *     各システムの更新の判断基準は、システムID=各システムのバージョン番号がアップされた場合です。
069 *
070 *     更新スクリプトは、
071 *      webapps/[CONTEXT]/db/[DBNAME]/xml/update                        DBID=DEFAULT
072 *     以下にあるXMLファイルが全て実行されます。
073 *     また、同時に
074 *      webapps/[CONTEXT]/db/common/xml/update                          DBID=DEFAULT
075 *      webapps/[CONTEXT]/db/resource/xml/update                        DBID=RESOURCE   (5.6.7.0 (2013/07/27) 追加)
076 *     以下にあるデータロードスクリプトも全て実行されます。
077 *
078 * (2)インストール(#install)
079 *  自動インストールは、通常は画面からコンテキストのアーカイブを指定して行います。
080 *
081 *  アーカイブの内容としては、アーカイブの直下がコンテキスト名のフォルダとなっている必要があります。
082 *  このコンテキストフォルダをwebapps以下に展開します。
083 *
084 *  また、Tomcatのコンテキストの設定ファイル、([CONTEXT].xml)が"WEB-INFの直下を配置している必要があります。
085 *
086 *  このインストールでは、Tomcatに対するコンテキスト定義のXMLファイルの配備及び、
087 *  各種DB、データのロードを行います。
088 *
089 *  インストールスクリプトは、
090 *   webapps/[CONTEXT]/db/[DBNAME]/xml/install                          DBID=DEFAULT
091 *  以下にあるXMLファイルが全て実行されます。
092 *  また、同時に
093 *   webapps/[CONTEXT]/db/common/xml/install                            DBID=DEFAULT
094 *   webapps/[CONTEXT]/db/resource/xml/install                          DBID=RESOURCE   (5.6.7.0 (2013/07/27) 追加)
095 *  以下にあるデータロードスクリプトも全て実行されます。
096 *
097 * @og.rev 4.3.6.6 (2009/05/15) 新規作成
098 * @og.group 初期化
099 *
100 * @version  4.0
101 * @author   Hiroki Nakamura
102 * @since    JDK5.0,
103 */
104public final class SystemInstaller {
105//      private final String VERSION;                   // 5.5.4.4 (2012/07/20) VERSION は、直接 BuildNumber.ENGINE_INFO を使用。
106//      private final Connection connection;
107        private final Connection defConn;               // 5.6.7.0 (2013/07/27) DBID=DEFAULT  のコネクション
108        private final Connection rscConn;               // 5.6.7.0 (2013/07/27) DBID=RESOURCE のコネクション
109        private final PrintWriter out;                  // 5.1.9.0 (2010/08/01)
110        private final String DBNAME;                    // 5.5.4.4 (2012/07/20) 共通化 (DBID=DEFAULT のDB名)
111
112        /** エンジン共通パラメータ(SYSTEM_ID='**' KBSAKU='0')のXML ファイルの指定  {@value}        */
113        public static final String GE12_XML = "org/opengion/hayabusa/common/GE12.xml";
114
115        /** エンジン共通パラメータ(SYSTEM_ID='**' KBSAKU='0')のENGINE_INFO 読み取りクエリー {@value}        */
116        public static final String SEL_MAX_ENG = "select PARAM from GE12"
117                                                                        + " where SYSTEM_ID='**' and PARAM_ID='ENGINE_INFO'"
118                                                                        + " and FGJ='1' and KBSAKU='0'" ;
119
120        /** エンジン個別(SYSTEM_ID='個別' KBSAKU='0'  CONTXT_PATH='自身')のバージョン情報を取得するクエリーー{@value} 4.3.6.6 (2009/05/15) */
121        public static final String SEL_SYS_ENG = "select PARAM from GE12"
122                                                                        + " where SYSTEM_ID=? and PARAM_ID='ENGINE_INFO' and KBSAKU='0' and CONTXT_PATH=? and FGJ='1'";
123
124        private static final String FS                  = File.separator ;                                              // 5.5.4.4 (2012/07/20) static化
125//      private static final String APP_BASE    = System.getenv( "APP_BASE" ) + FS;             // 5.5.4.4 (2012/07/20) static化
126        private static final String APP_BASE    = StringUtil.nval(System.getenv( "APP_BASE" ),System.getProperty( "APP_BASE" )) + FS; // 5.9.30.2 (2018/03/23)
127
128
129        /**
130         * データベース処理をおこなうに当たり、処理のタイプを指定するための、enum 定義です。
131         * 文字列で扱っていた箇所を、enum と置き換えます。
132         *
133         * @og.rev 5.5.4.4 (2012/07/20) 新規追加
134         */
135        private static enum EXEC_TYPE { INSTALL , UPDATE } ;
136
137        /**
138         * システムインストール・更新クラスのコンストラクタです
139         *
140         * なお、このクラスの中の処理で、エラーが発生しても、Connection は、close 等しません。
141         * 呼び出し元で、try 〜 finally で、処理してください。
142         *
143         * @og.rev 5.5.4.4 (2012/07/20) VERSIONは、直接 BuildNumber.ENGINE_INFO を使用。
144         * @og.rev 5.6.7.0 (2013/07/27) アプリケーション登録用とリソース登録用のコネクションを分ける
145         * @og.rev 5.9.19.0 (2017/04/07) DBNAMEの取得をタイプにする
146         * @og.rev 5.9.24.1 (2017/09/08) DB名を出力する
147         *
148         * @param       defConn アプリケーション登録用コネクション
149         * @param       rscConn リソース登録用コネクション
150         * @param       out     表示用のWriter
151         */
152//      public SystemInstaller( final Connection conn, final PrintWriter out ) {
153        public SystemInstaller( final Connection defConn, final Connection rscConn, final PrintWriter out ) {
154//              connection = conn;
155                this.defConn = defConn;                 // 5.6.7.0 (2013/07/27) アプリケーション登録用
156                this.rscConn = rscConn;                 // 5.6.7.0 (2013/07/27) リソース登録用
157                this.out = out;
158
159//              VERSION = BuildNumber.ENGINE_INFO;
160
161                // 5.6.7.0 (2013/07/27) ProductName は、DBUtil 経由で取得する。
162//              String dbName ;
163//              try {
164//                      dbName = connection.getMetaData().getDatabaseProductName().toLowerCase( Locale.JAPAN );
165//              }
166//              catch( SQLException ex ) {
167//                      out.println( "        -> DatabaseProductName is NONE " + ex.getMessage() );
168//                      dbName = "none";
169//              }
170//              DBNAME = dbName;
171
172//              DBNAME = DBUtil.getProductName( defConn );              // 5.6.7.0 (2013/07/27) DBID=DEFAULT  のDB名
173//              DBNAME = DBUtil.getDBType( DBUtil.getProductName( defConn )); //5.9.19.0 (2017/04/07) DB種別で取るようにする
174                String DBPdcName = DBUtil.getProductName( defConn ); // 5.9.24.1 productNameの表示
175                out.println( "    Database Information ( " + DBPdcName + " )" ); 
176                DBNAME = DBUtil.getDBType(DBPdcName); 
177        }
178
179        /**
180         * システムの初期自動インストール・自動更新を行います。
181         *
182         * 詳細は、クラスドキュメントを参照して下さい。
183         *
184         * @og.rev 5.1.9.0 (2010/08/01) 新規作成
185         * @og.rev 5.5.4.4 (2012/07/20) VERSIONは、直接 BuildNumber.ENGINE_INFO を使用。
186         * @og.rev 5.9.30.2 (2018/03/23) getenvで値が取得できない場合にgetPropertyを利用する
187         *
188         * @param systemId システムID
189         * @param context コンテキスト名
190         * @param hostUrl ホスト文字列
191         * @throws UnsupportedEncodingException エンコード名 "UTF-8" が存在しなかった場合。
192         * @see   #dbXMLResourceInsert()
193         */
194//      public void autoInsUpd( final String systemId, final String context, final String hostUrl ) throws SQLException, UnsupportedEncodingException  {
195        public void autoInsUpd( final String systemId, final String context, final String hostUrl ) throws UnsupportedEncodingException  {
196                String oldMaxVersion = getOldMaxVersion();
197                String oldSystemVersion = getOldSystemVersion( systemId, hostUrl );
198
199                out.println( "    System Version Information ( " + systemId + " )" );
200//              out.println( "      Load Version [ " + VERSION + " ]" );
201                out.println( "      Load Version [ " + BuildNumber.ENGINE_INFO + " ]" );                // 5.5.4.4 (2012/07/20)
202                out.println( "        -> Resource Version[ " + oldMaxVersion + " ]" );
203                out.println( "        -> System   Version[ " + oldSystemVersion + " ]" );
204
205                // 初期自動インストール
206                if( "none".equalsIgnoreCase( oldMaxVersion ) ) {
207                        out.println( "      !!! openGion ENVIROMENT IS NOT INSTALLED !!!" );
208
209//                      String INSTALL_CONTEXTS = System.getenv( "INSTALL_CONTEXTS" );
210                        String INSTALL_CONTEXTS = StringUtil.nval( System.getenv( "INSTALL_CONTEXTS" ), System.getProperty( "INSTALL_CONTEXTS" ) ); // 5.9.30.2 (2018/03/23) 
211                        if( INSTALL_CONTEXTS == null || INSTALL_CONTEXTS.length() == 0 ) {
212                                out.println( "        !!! \"INSTALL_CONTEXT\" IS NOT CONFIGURED\" !!!" );
213                                out.println( "        !!! \"SET ENRIVOMENT PARAMETER NAMED \"INSTALL_CONTEXT\" ON INIT_SCRIPT !!!" );
214                                return;
215                        }
216                        out.println( "      Start Initiall Enviroment Install : install type ( " + INSTALL_CONTEXTS + " )" );
217                        String[] insSys = StringUtil.csv2Array( INSTALL_CONTEXTS );
218                        for( int i=0; i<insSys.length; i++ ) {
219                                out.println( "        install    ( " + insSys[i] + " )" );
220//                              loadXMLScript( "install", insSys[i] );
221                                loadXMLScript( EXEC_TYPE.INSTALL, insSys[i] );
222//                              connection.commit();
223//                              Closer.commit( connection );                            // 5.5.4.4 (2012/07/20) commit で、SQLException を発生させない。
224                                out.println( "        completed  ( " + insSys[i] + " )" );
225                        }
226
227                        out.println( "      Start SystemParameter reload" );
228                        dbXMLResourceInsert();
229//                      connection.commit();
230//                      Closer.commit( connection );                            // 5.5.4.4 (2012/07/20) commit で、SQLException を発生させない。
231                        out.println( "      completed" );
232                }
233                // 自動更新
234                else {
235//                      if ( oldSystemVersion == null || oldSystemVersion.compareTo( VERSION ) < 0 ){
236                        if ( oldSystemVersion == null || oldSystemVersion.compareTo( BuildNumber.ENGINE_INFO ) < 0 ){                // 5.5.4.4 (2012/07/20)
237                                out.println( "      Start Enviroment Update ( " + context + " )" );
238//                              loadXMLScript( "update", context );
239                                loadXMLScript( EXEC_TYPE.UPDATE , context );
240//                              connection.commit();
241//                              Closer.commit( connection );                            // 5.5.4.4 (2012/07/20) commit で、SQLException を発生させない。
242                                out.println( "      completed               ( " + context + " )" );
243                        }
244
245//                      if( oldMaxVersion == null || oldMaxVersion.compareTo( VERSION ) < 0 ){
246                        if( oldMaxVersion == null || oldMaxVersion.compareTo( BuildNumber.ENGINE_INFO ) < 0 ){                               // 5.5.4.4 (2012/07/20)
247                                out.println( "      Start SystemParameter Reload" );
248                                dbXMLResourceInsert();
249//                              connection.commit();
250//                              Closer.commit( connection );                            // 5.5.4.4 (2012/07/20) commit で、SQLException を発生させない。
251                                out.println( "      completed" );
252                        }
253                }
254        }
255
256        /**
257         * システムの自動インストールを行います。
258         *
259         * 詳細は、クラスドキュメントを参照して下さい。
260         *
261         * @og.rev 5.1.9.0 (2010/08/01) 新規作成
262         * @og.rev 5.5.4.4 (2012/07/20) FS , APP_BASE を、共通に設定
263         * @og.rev 5.9.30.2 (2018/03/23) getenvで値が取得できない場合にgetPropertyを利用する
264         *
265         * @param buildArchive コンテキストのアーカイブファイル
266         */
267//      public void install( final File buildArchive ) throws SQLException {
268        public void install( final File buildArchive ) {
269//              final String FS       = File.separator ;
270//              final String tempDir  = HybsSystem.sys( "REAL_PATH" ) + HybsSystem.sys( "FILE_URL" ) + String.valueOf( System.currentTimeMillis() + FS );
271                final String tempDir  = HybsSystem.sys( "REAL_PATH" ) + HybsSystem.sys( "FILE_URL" ) + System.currentTimeMillis() + FS;
272//              final String ctxtXmlDir = System.getenv( "CATALINA_HOME" ) + FS + "conf" + FS + System.getenv( "ENGINE_NAME" ) + FS + "localhost" + FS;
273                final String ctxtXmlDir = StringUtil.nval( System.getenv( "CATALINA_HOME" ), System.getProperty( "CATALINA_HOME" )) + FS 
274                                                                        + "conf" + FS +  StringUtil.nval( System.getenv( "ENGINE_NAME" ), System.getProperty( "ENGINE_NAME" ) ) + FS + "localhost" + FS;
275
276//              final String appBase  = System.getenv( "APP_BASE" ) + FS;               // 5.5.4.4 (2012/07/20) APP_BASE を共通に設定
277
278                out.println( "      Check Archive File and Enviroment" );
279
280                // アーカイブの存在チェック
281                if( !buildArchive.exists() ) {
282                        out.println( "        !!! Archive File does not exists File=[ " + buildArchive.getAbsolutePath() + "] !!!" );
283                        out.println( "        !!! Install Aborted !!! " );
284                        return;
285                }
286
287                // アーカイブを一時ファイルに展開します。
288                ZipFileUtil.unCompress( tempDir, buildArchive.getAbsolutePath() );
289
290                // アーカイブの内容チェック
291                File[] ctxts = new File( tempDir ).listFiles();
292                for( File ctxt : ctxts ) {
293                        // 5.1.9.0 (2010/08/01) if の条件を入れ替えます。(Avoid if (x != y) ..; else ..;)
294                        String context = ctxt.getName();
295                        if( ctxt.isDirectory() ) {
296//                              String context = ctxt.getName();
297
298                                // アーカイブ中に[CONTEXT].xmlが存在していない場合はエラー(何も処理しない)
299                                File srcCtxtXml = new File( tempDir + context + FS + "WEB-INF" + FS + context + ".xml" );
300                                if( !srcCtxtXml.exists() ) {
301                                        out.println( "        !!! Context XML Does not exists =[ " + srcCtxtXml.getAbsolutePath() + "] !!!" );
302                                        out.println( "        !!! Install Aborted !!! " );
303                                        return;
304                                }
305
306                                // [CONTEXT].xmlが既に存在している場合はエラー(何も処理しない)
307                                File ctxtXml = new File(  ctxtXmlDir + context + ".xml" );
308                                if( ctxtXml.exists() ) {
309                                        out.println( "        !!! Context XML File Already Installed File=[ " + ctxtXml.getAbsolutePath() + "] !!!" );
310                                        out.println( "        !!! Install Aborted !!! " );
311                                        return;
312                                }
313
314                                // webapps/[CONTEXT]が既に存在している場合はエラー(何も処理しない)
315//                              File webAppsDir = new File( appBase + context );                // 5.5.4.4 (2012/07/20) APP_BASE を共通に設定
316                                File webAppsDir = new File( APP_BASE + context );
317                                if( webAppsDir.exists() ) {
318                                        out.println( "        !!! Context Path Already Exists Path=[ " + webAppsDir.getAbsolutePath() + "] !!!" );
319                                        out.println( "        !!! Install Aborted !!! " );
320                                        return;
321                                }
322
323//                              out.println( "        This Archive includes SYSTEM ( " + ctxt.getName() + " ) for Install" );
324                                out.println( "        This Archive includes SYSTEM ( " + context + " ) for Install" );                  // 5.5.4.4 (2012/07/20)
325                        }
326                        // ファイルが含まれている場合はエラー(何も処理しない)
327                        else {
328//                              out.println( "        !!! This Archive is not Installer. Because include FILE not DIRECTORY. File=[ " + ctxt.getName() + "] !!!" );
329                                out.println( "        !!! This Archive is not Installer. Because include FILE not DIRECTORY. File=[ " + context + "] !!!" );    // 5.5.4.4 (2012/07/20)
330                                out.println( "        !!! Install Aborted !!! " );
331                                return;
332                        }
333                }
334
335                // アーカイブをコンテキストファイル以下にコピー
336                for( File ctxt : ctxts ) {
337                        String context = ctxt.getName();
338                        out.println( "      Start Enviroment Install ( " + context + " )" );
339
340                        // コンテキストのファイルをコピーします。
341//                      FileUtil.copyDirectry( tempDir + context, appBase + context );          // 5.5.4.4 (2012/07/20) APP_BASE を共通に設定
342                        FileUtil.copyDirectry( tempDir + context, APP_BASE + context );
343
344                        // [CONTEXT].xmlをTomcatのconf以下に展開します。
345                        FileUtil.copy( tempDir + context + FS + "WEB-INF" + FS + context + ".xml", ctxtXmlDir + context + ".xml" );
346
347                        // DBスクリプトをロードします。
348//                      loadXMLScript( "install", context );
349                        loadXMLScript( EXEC_TYPE.INSTALL , context );
350//                      connection.commit();
351//                      Closer.commit( connection );                            // 5.5.4.4 (2012/07/20) commit で、SQLException を発生させない。
352                        out.println( "      completed                ( " + context + " )" );
353                }
354                out.println( "      Install Process All Completed." );
355        }
356
357        /**
358         * インストール、更新用のXMLスクリプトをロードします。
359         *
360         * @og.rev 5.0.0.2 (2009/09/15) .xmlファイル以外は読み込まないように修正
361         * @og.rev 5.1.1.0 (2009/12/01) コメントを出して、処理中ということが判る様にします。
362         * @og.rev 5.1.9.0 (2010/08/01) DB非依存の定義・データの読み込み対応
363         * @og.rev 5.5.4.4 (2012/07/20) FS , APP_BASE , DBNAME を、共通に設定
364         * @og.rev 5.6.7.0 (2013/07/27) アプリケーション登録用とリソース登録用のコネクションを分ける
365         *
366         * @param       type    更新タイプ[EXEC_TYPE.INSTALL/EXEC_TYPE.UPDATE]
367         * @param       context コンテキスト名
368         */
369//      private void loadXMLScript( final String type, final String context ) throws SQLException {
370        private void loadXMLScript( final EXEC_TYPE type, final String context ) {
371//              final String FS       = File.separator ;
372//              final String APP_BASE = System.getenv( "APP_BASE" );            // 5.5.4.4 (2012/07/20) APP_BASE を共通に設定
373//              final String DBNAME   = connection.getMetaData().getDatabaseProductName().toLowerCase( Locale.JAPAN );
374
375                // DB名からスクリプトを格納しているフォルダを探します。
376//              String scriptBase = APP_BASE + FS + context.toLowerCase( Locale.JAPAN ) + FS + "db";
377                String scriptBase = APP_BASE + context.toLowerCase( Locale.JAPAN ) + FS + "db";
378                File[] dbDir = new File( scriptBase ).listFiles();
379                if( dbDir == null || dbDir.length == 0 ) {
380                        out.println( "             DB Folder not found. [" + scriptBase + "]"  );
381                        return;
382                }
383
384                String scriptPath = null;
385                for ( int i = 0; i < dbDir.length; i++ ) {
386                        if ( DBNAME.indexOf( dbDir[i].getName() ) >= 0 ) {
387                                scriptPath = dbDir[i].getAbsolutePath();
388                                break;
389                        }
390                }
391                if( scriptPath == null ) {
392                        out.println( "             !!! Script Folder for [ " + DBNAME + " ] not found !!!" );
393                        return;
394                }
395
396                // webapps/[CONTEXT]/db/[DBNAME]/
397//              execScripts( scriptPath, type );
398//              execScripts( type , scriptPath );                               // 5.5.4.4 (2012/07/20) typeのenum化と、引数の順番を親に合わす。
399                execScripts( type , scriptPath , defConn );             // 5.6.7.0 (2013/07/27) DBID=DEFAULT に登録
400
401                // 5.1.9.0 (2010/08/01) DB非依存の定義・データの読み込み対応
402                // webapps/[CONTEXT]/db/common/
403//              execScripts( scriptBase + FS + "common" + FS, type );
404//              execScripts( type , scriptBase + FS + "common" );                               // 5.5.4.4 (2012/07/20) typeのenum化と、引数の順番を親に合わす。
405                execScripts( type , scriptBase + FS + "common" , defConn );             // 5.6.7.0 (2013/07/27) DBID=DEFAULT に登録
406
407                // 5.6.7.0 (2013/07/27) DBID=RESOURCE に登録
408                // webapps/[CONTEXT]/db/resource/
409                execScripts( type , scriptBase + FS + "resource" , rscConn );   // 5.6.7.0 (2013/07/27) DBID=RESOURCE に登録
410
411//              // webapps/[CONTEXT]/db/xml 内のスクリプトを実行します
412//              File[] dataDir = new File( scriptBase + FS + "xml" ).listFiles();
413//              if( dataDir != null && dataDir.length > 0 ) {
414//                      for ( int i=0; i<dataDir.length; i++ ) {
415//                              String dtNm = dataDir[i].getName() ;
416//                              if( dtNm.endsWith( ".xml" ) ) {         // 5.0.0.2 (2009/09/15)
417//                                      Reader reader = new BufferedReader( FileUtil.getBufferedReader( dataDir[i], "UTF-8" ) );
418//                                      HybsXMLSave save = new HybsXMLSave( connection, dtNm );
419//                                      save.insertXML( reader );
420//                              }
421//                      }
422//                      out.println( "            DB Data Files Installed , [ " + dataDir.length + " ] files loaded " );
423//              }
424        }
425
426        /**
427         * XMLファイルで定義されたDBスクリプトを実行します。
428         *
429         * 引数のtypeに応じて、処理するフォルダが異なります。
430         *   type=INSTALL の場合は、[scriptPath]/xml/install と、[scriptPath]/xml/update 以下の xml ファイル
431         *   type=それ以外の場合は、[scriptPath]/xml/update 以下の xml ファイル
432         * です。
433         *
434         * 現時点では、scriptPath には、下記の 3種類のアドレスが渡され、それぞれ、登録するコネクションが異なります。
435         *   webapps/[CONTEXT]/db/[DBNAME]/                     DBID=DEFAULT
436         *   webapps/[CONTEXT]/db/common/                       DBID=DEFAULT
437         *   webapps/[CONTEXT]/db/resource/                     DBID=RESOURCE
438         *
439         * @og.rev 5.1.9.0 (2010/08/01) 新規作成
440         * @og.rev 5.5.4.4 (2012/07/20) FS , APP_BASE を、共通に設定
441         * @og.rev 5.5.8.4 (2012/11/22) firebird対応。フォルダ単位commitを行う
442         * @og.rev 5.6.7.0 (2013/07/27) Connection引数追加。リソースとアプリを切り分ける。
443         * @og.rev 5.6.9.2 (2013/10/18) EXEC_SQL のエラー時に Exception を発行しない。
444         *
445         * @param       type            更新タイプ[EXEC_TYPE.INSTALL/EXEC_TYPE.UPDATE]
446         * @param       scriptPath      XMLファイルのあるパス
447         * @param       conn            コネクションオブジェクト
448         */
449//      private void execScripts( final String scriptPath, final String type ) {
450//      private void execScripts( final EXEC_TYPE type, final String scriptPath ) {
451        private void execScripts( final EXEC_TYPE type, final String scriptPath, final Connection conn ) {
452//              final String FS       = File.separator ;
453
454                // webapps/[CONTEXT]/db/[DBNAME]/xml/(install|update) 内のスクリプトを実行します
455                List<String> list = new ArrayList<String>();
456
457//              if( "install".equalsIgnoreCase( type ) ) {
458                if( type == EXEC_TYPE.INSTALL ) {
459                        FileUtil.getFileList( new File( scriptPath  + FS + "xml" + FS + "install" ), true, list );
460//                      FileUtil.getFileList( new File( scriptPath  + FS + "xml" + FS + "update" + FS + "const" ), true, list );
461                        FileUtil.getFileList( new File( scriptPath  + FS + "xml" + FS + "update"  ), true, list );
462                }
463                else {
464//                      FileUtil.getFileList( new File( scriptPath  + FS + "xml" + FS + "update" + FS + "const" ), true, list );
465                        FileUtil.getFileList( new File( scriptPath  + FS + "xml" + FS + "update"  ), true, list );
466
467                        /*******************************************************************************
468                         * updateの場合に、更新前のバージョンからの変更スクリプトを実行する機能が必要
469                         *******************************************************************************/
470                }
471
472                if( ! list.isEmpty() ) {
473                        String dir1 = null;             // 5.1.1.0 (2009/12/01)
474                        for ( String name : list ) {
475                                if( name.endsWith( ".xml" ) ) {         // 5.0.0.2 (2009/09/15)
476                                        File xml = new File( name );
477                                        // 5.1.1.0 (2009/12/01) 処理中コメント:フォルダ単位に表示
478                                        String dir2 = xml.getParent();
479                                        if( dir1 == null || !dir1.equalsIgnoreCase( dir2 ) ) {
480                                                out.println( "            processing ... " + dir2 );
481                                                dir1 = dir2;
482//                                              Closer.commit( connection );    // 5.5.8.4 (2012/11/22)
483                                                Closer.commit( conn );                  // 5.6.7.0 (2013/07/27) Connection引数追加
484                                        }
485
486                                        Reader reader = new BufferedReader( FileUtil.getBufferedReader( xml, "UTF-8" ) );
487//                                      HybsXMLSave save = new HybsXMLSave( connection, xml.getName() );
488                                        HybsXMLSave save = new HybsXMLSave( conn, xml.getName() );                      // 5.6.7.0 (2013/07/27) Connection引数追加
489                                        save.onExecErrException( false );               // 5.6.9.2 (2013/10/18) EXEC_SQL のエラー時に Exception を発行しない。
490                                        save.insertXML( reader );
491                                }
492                        }
493                        Closer.commit( conn );                  // 5.6.7.0 (2013/07/27) メソッド内でコミット処理を行う。
494                        out.println( "            DB Enviroment " + type + "ed , [ " + list.size() + " ] scripts loaded " );
495                }
496        }
497
498        /**
499         * 最後に起動された際のバージョン番号を取得します。(システムID='**')
500         *
501         * エンジンがまだインストールされていない等の原因でエラーが発生した場合は、
502         * "none"という文字列を返します。
503         *
504         * @og.rev 5.1.1.0 (2009/12/01) 実行エラー時に、rollback を追加(PostgreSQL対応)
505         * @og.rev 5.6.7.0 (2013/07/27) リソース用コネクションから取り出します。
506         * @og.rev 5.7.2.0 (2014/01/10) テーブルが無いのに正常終了するケースがある為、ver の初期値を "none" にしておきます。
507         *
508         * @return      バージョン番号
509         */
510        private String getOldMaxVersion() {
511                // エンジンパラメータのエンジン情報(バージョン番号 + ビルドタイプ)を取得します。
512                Statement                       stmt            = null;
513                ResultSet                       resultSet       = null;
514//              String                          ver             = null;
515                String                          ver             = "none";                               // 5.7.2.0 (2014/01/10) 初期値を null ⇒ "none" へ変更。
516                try {
517//                      stmt = connection.createStatement();
518                        stmt = rscConn.createStatement();                                       // 5.6.7.0 (2013/07/27)
519                        resultSet = stmt.executeQuery( SEL_MAX_ENG );
520                        while( resultSet.next() ) {
521                                ver = resultSet.getString(1);
522                        }
523                }
524                catch( SQLException ex ) {
525//                      ver = "none";                                           // 5.7.2.0 (2014/01/10) 初期値を変更したため、設定不要。
526//                      Closer.rollback( connection );          // 5.1.1.0 (2009/12/01)
527                        Closer.rollback( rscConn );                     // 5.6.7.0 (2013/07/27)
528                }
529                finally {
530                        Closer.resultClose( resultSet );
531                        Closer.stmtClose( stmt );
532                }
533                return ver;
534        }
535
536        /**
537         * 最後に起動された際のバージョン番号を取得します。(システムID=各システム)
538         *
539         * @og.rev 5.1.1.0 (2009/12/01) 実行エラー時に、rollback を追加(PostgreSQL対応)
540         * @og.rev 5.6.7.0 (2013/07/27) リソース用コネクションから取り出します。
541         *
542         * @param       systemId        システムID
543         * @param       hostUrl         ホストURL
544         *
545         * @return      バージョン番号
546         */
547        private String getOldSystemVersion( final String systemId, final String hostUrl ) {
548                // エンジンパラメータのエンジン情報(バージョン番号 + ビルドタイプ)を取得します。
549                PreparedStatement       pstmt           = null;
550                ResultSet                       resultSet       = null;
551                String                          ver             = null;
552                try {
553//                      pstmt = connection.prepareStatement( SEL_SYS_ENG );
554                        pstmt = rscConn.prepareStatement( SEL_SYS_ENG );                // 5.6.7.0 (2013/07/27)
555                        pstmt.setString( 1, systemId );
556                        pstmt.setString( 2, hostUrl );
557                        resultSet = pstmt.executeQuery();
558                        while( resultSet.next() ) {
559                                ver = resultSet.getString(1);
560                        }
561                }
562                catch( SQLException ex ) {
563//                      Closer.rollback( connection );          // 5.1.1.0 (2009/12/01)
564                        Closer.rollback( rscConn );                     // 5.6.7.0 (2013/07/27)
565                }
566                finally {
567                        Closer.resultClose( resultSet );
568                        Closer.stmtClose( pstmt );
569                }
570                return ver;
571        }
572
573        /**
574         * エンジン内部定義の初期リソース情報をDB(GE12)に登録します。
575         *
576         * 初期リソース情報は、KBSAKU='0' で登録されている情報で、一旦すべて削除
577         * してから、全てのリソース情報を追加するという形をとります。
578         * リソースは、すでに、Oracle XDK により XMLファイル化してあります。
579         * なお、この情報をDB登録する理由は、リソースの設定値を変えたい場合に、
580         * キーが判らない(JavaDOCからしか読み取れない)のでは不便な為に
581         * 用意しておくだけで、内部では SystemData オブジェクトとして定義
582         * されている値を使用するため、このデータベース値は、使用していません。
583         *
584         * @og.rev 4.3.6.6 (2009/05/15) バージョン判定部分を分離
585         * @og.rev 5.6.7.0 (2013/07/27) リソース用コネクションに登録します。
586         * @og.rev 5.6.9.2 (2013/10/18) EXEC_SQL のエラー時に Exception を発行しない。
587         *
588         * @throws UnsupportedEncodingException エンコード名 "UTF-8" が存在しなかった場合。
589         */
590        private void dbXMLResourceInsert() throws UnsupportedEncodingException {
591                // 新設定値を全件INSERTします。
592                // common フォルダにセットして、ClassLoader で読み取る方法
593                ClassLoader loader = Thread.currentThread().getContextClassLoader();
594                InputStream stream = loader.getResourceAsStream( GE12_XML );
595
596                Reader reader = new BufferedReader( new InputStreamReader( stream,"UTF-8" ) );
597//              HybsXMLSave save = new HybsXMLSave( connection,"GE12" );
598                HybsXMLSave save = new HybsXMLSave( rscConn,"GE12" );                   // 5.6.7.0 (2013/07/27)
599                save.onExecErrException( false );               // 5.6.9.2 (2013/10/18) EXEC_SQL のエラー時に Exception を発行しない。
600                save.insertXML( reader );
601                int insCnt = save.getInsertCount();
602                int delCnt = save.getDeleteCount();
603
604                out.print( "        XML Engine Resource Reconfiguration " );
605                out.println( "DELETE=[" + delCnt + "],INSERT=[" + insCnt + "] finished." );
606
607                // 5.6.7.0 (2013/07/27) コミットをメソッドの中で処理します。
608                Closer.commit( rscConn );
609        }
610}