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