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