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.plugin.daemon; 017 018import org.opengion.hayabusa.common.HybsSystem; 019import org.opengion.hayabusa.common.HybsSystemException; 020import org.opengion.hayabusa.report.GE50Access; 021import org.opengion.hayabusa.report.ReportProcessing; 022import org.opengion.fukurou.system.LogWriter; 023import org.opengion.fukurou.util.StringUtil; 024import org.opengion.fukurou.system.ThrowUtil; // 6.4.2.0 (2016/01/29) 025import org.opengion.fukurou.util.HybsTimerTask; 026import org.opengion.fukurou.db.ApplicationInfo; 027import org.opengion.fukurou.db.DBUtil; 028import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE; // 6.1.0.0 (2014/12/26) refactoring 029 030import java.util.concurrent.ConcurrentMap; // 6.4.3.3 (2016/03/04) 031import java.util.concurrent.ConcurrentHashMap; // 6.4.3.1 (2016/02/12) refactoring 032import java.util.Date; 033 034/** 035 * 【レポート出力】帳票要求テーブルを監視して、帳票処理プログラムを呼び出します。 036 * このクラスは、HybsTimerTask を継承した タイマータスククラスです。 037 * startDaemon() がタイマータスクによって、呼び出されます。 038 * 039 * @og.rev 4.3.4.4 (2009/01/01) プラグイン化 040 * @og.group デーモン 041 * 042 * @version 4.0 043 * @author Kazuhiko Hasegawa 044 * @since JDK5.0, 045 */ 046public class Daemon_Report extends HybsTimerTask { 047 /** このプログラムのVERSION文字列を設定します。 {@value} */ 048 private static final String VERSION = "6.4.3.3 (2016/03/04)" ; 049 050 /** コネクションにアプリケーション情報を追記するかどうか指定 */ 051 public static final boolean USE_DB_APPLICATION_INFO = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ; 052 053 // 3.7.0.0 (2005/01/18) 複数同時デーモン時の、同一帳票IDは処理できない。 054 // 実行中の帳票ID をセットする、static Map 055 /** 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 */ 056 private static final ConcurrentMap<String,String> USE_LISTID = new ConcurrentHashMap<>(); // 6.4.3.1 (2016/02/12) 057 058 // 3.8.5.0 (2006/03/06) EXCELをオープンするファイル名に要求番号を使う場合は、true 059 private static final boolean EXCEL_NAME_USE_YKNO = HybsSystem.sysBool( "REPORT_EXCEL_NAME_USE_YKNO" ); 060 061// // 5.2.0.0 (2010/09/01) Ver4互換モード対応 062// // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止 063// private static final String OUT_FILE = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "OUTFILE" : "OUT_FILE"; 064// private static final String OUT_DIR = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "OUTDIR" : "OUT_DIR"; 065 066 // 3.7.0.0 (2005/01/18) GE53 に DMN_GRP追加による、検索条件の変更 067 // 5.1.0.0 (2009/11/04) OUTDIR ⇒ OUT_DIR , OUTFILE ⇒ OUT_FILE 068 // 5.2.0.0 (2010/09/01) Ver4互換モード対応 069 070 // 5.9.0.1 (2015/09/11) 071 // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止 072 // 5.10.0.0 (2018/06/08) SELECT区にC.FGNOML(メール不要フラグ)を追加 073 private static final String GE50_SELECT = 074// "SELECT A.SYSTEM_ID,A.YKNO,A.GROUPID,A.LISTID,A.JOKEN,A."+OUT_DIR+",A."+OUT_FILE+",A.USRSET" + 075// "SELECT A.SYSTEM_ID,A.YKNO,A.GROUPID,A.LISTID,A.JOKEN,A.OUT_DIR,A.OUT_FILE,A.USRSET" + 076 // "SELECT A.SYSTEM_ID,A.YKNO,A.GROUPID,A.LISTID,A.JOKEN,A.OUT_DIR,A.OUT_FILE,A.USRSET,C.FGNOML" + // 5.10.0.0 (2018/06/08) 077 "SELECT A.SYSTEM_ID,A.YKNO,A.GROUPID,A.LISTID,A.JOKEN,A.OUT_DIR,A.OUT_FILE,A.USRSET,'0' as FGNOML" + // 6.9.8.1 (2018/06/11) 078 " FROM GE50 A,GE53 B,GE54 C" + 079 " WHERE A.SYSTEM_ID = B.SYSTEM_ID" + 080 " AND A.JOKEN = B.JOKEN" + 081 " AND A.FGJ = '1'" + 082 " AND B.FGJ = '1'" + 083 " AND A.FGKAN = '1'" + 084 " AND A.SYSTEM_ID = C.SYSTEM_ID" + 085 " AND A.LISTID = C.LISTID"+ 086 " AND C.FGJ = '1'"; 087 088 private final String DBID = HybsSystem.sys( "RESOURCE_DBID" ); // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応 089 090 // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 091 private ApplicationInfo appInfo ; 092 private ReportProcessing rc ; 093 094 private static final int LOOP_COUNTER = 24; // カウンタを24回に設定 095 private int loopCnt ; // 3.5.4.9 (2004/02/25) メッセージ出力時のループカウント 096 097 // 6.3.9.0 (2015/11/06) Variables should start with a lowercase character(PMD) 098 private String geSELECT ; // 3.7.0.0 (2005/01/18) GE53 に DMN_GRP追加による、検索条件の変更 099 private String prtID ; // 3.8.5.0 (2006/03/06) プリンタIDが、引数から渡される場合の対応 100 private String dmnNAME ; // 3.8.5.0 (2006/03/06) デーモン名を設定します。 101 private boolean debug ; // 3.8.5.0 (2006/03/06) デバッグ用のフラグを追加します。小文字に修正 102 private boolean running = true; // 3.8.5.3 (2006/06/30) タイマータスクがキャンセルされた場合の停止フラグ 103 104 /** 105 * デフォルトコンストラクター 106 * 107 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 108 */ 109 public Daemon_Report() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 110 111 /** 112 * このタイマータスクによって初期化されるアクションです。 113 * パラメータを使用した初期化を行います。 114 * 115 * @og.rev 3.6.0.7 (2004/11/12) 新規追加 116 * @og.rev 3.7.0.0 (2005/01/18) 帳票定義マスタ(GE54)を参照するように仕様変更 117 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 118 * @og.rev 4.0.1.0 (2007/12/19) GE50の検索順をシステムリソースで設定可能にする 119 * @og.rev 5.7.3.2 (2014/02/28) GE53の検索条件修正 120 */ 121 @Override 122 public void initDaemon() { 123 124 // 3.7.0.0 (2005/01/18) GE50, GE54 の USRUPD に、デーモン名をセットします。 125 // 3.7.1.1 (2005/05/31) GE50Access を使用して、DB登録を行います。 126 127 // 3.8.5.0 (2006/03/06) デーモン名を設定します。 128 dmnNAME = getName(); // 6.3.9.0 (2015/11/06) 129 130 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 131 buf.append( GE50_SELECT ); 132 133 // SYSTEM_ID は、指定がなければ、全件検索対象になります。 134 final String systemId = getValue( "SYSTEM_ID" ); 135 if( ! StringUtil.isNull( systemId ) ) { 136 buf.append( " AND A.SYSTEM_ID='" ).append( systemId ).append( '\'' ); 137 } 138 139 // 3.8.5.0 (2006/03/06) DMN_GRP は、必須指定 140 // 5.1.9.0 (2010/08/01) Avoid if(x != y) ..; else ..; 141 final String dmnGroup = getValue( "DMN_GRP" ); 142 if( StringUtil.isNull( dmnGroup ) ) { 143 final String errMsg = "デーモングループは必須指定です。" ; 144 throw new HybsSystemException( errMsg ); 145 } 146 else { 147 buf.append( " AND B.DMN_GRP='" ).append( dmnGroup ).append( '\'' ); 148 } 149 150 // 3.8.5.0 (2006/03/06) GE50 の検索条件に、MODBASE と MODNO を使用する。 151 // デーモン起動時に 最大数(MODBASE)と余り番号(MODNO)を渡します。 152 // 最大数(MODBASE)を元に、検索時に、YKNOの余りを求め、これが、 153 // 引数の余り番号(MODNO)と一致する場合のみ、処理をします。 154 final String modBase = StringUtil.nval( getValue( "MODBASE" ),null ); 155 final String modNo = StringUtil.nval( getValue( "MODNO" ),null ); 156 if( modBase != null && modNo != null ) { 157 buf.append( " AND MOD(A.YKNO," ).append( modBase ).append( ")=" ).append( modNo ); 158 } 159 160 // 3.8.5.0 (2006/03/06) PRTID が指定されていれば、その値を使用する。なければ NULL 161 prtID = StringUtil.nval( getValue( "PRTID" ), null ); // 6.3.9.0 (2015/11/06) 162 163 // 3.8.5.0 (2006/03/06) PRT_GRP が指定されていれば、振分条件検索時に使用する。 164 final String prtGgrp = getValue( "PRT_GRP" ); 165 if( ! StringUtil.isNull( prtGgrp ) ) { 166 buf.append( " AND B.PRTID='" ).append( prtGgrp ).append( '\'' ); // 5.7.3.2 (2014/02/28) GE53ではPRTIDにPRI_GRPが指定されている 167 } 168 169 buf.append( " ORDER BY " ) // 4.0.1.0 (2007/12/19) 170 .append( HybsSystem.sys( "REPORT_DAEMON_ORDER_BY" ) ); 171 172 geSELECT = buf.toString() ; // 6.3.9.0 (2015/11/06) 173 174 // 3.8.5.0 (2006/03/06) デバッグ用のフラグを追加します。 175 debug = StringUtil.nval( getValue( "DEBUG" ),debug ) ; 176 177 if( debug ) { 178 System.out.println( "DMN_NAME=[" + dmnNAME + "]" ); // 6.3.9.0 (2015/11/06) 179 System.out.println( "MODNO=[" + modNo + "]" ); 180 System.out.println( "QUERY=[" + geSELECT + "]" ); 181 System.out.println( "EXCEL_NAME_USE_YKNO=[" + EXCEL_NAME_USE_YKNO + "]" ); 182 } 183 184 // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 185 if( USE_DB_APPLICATION_INFO ) { 186 appInfo = new ApplicationInfo(); 187 // ユーザーID,IPアドレス,ホスト名 188 appInfo.setClientInfo( systemId,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME ); 189 // 画面ID,操作,プログラムID 190 appInfo.setModuleInfo( "ReportDaemon",prtID,dmnNAME ); // 6.3.9.0 (2015/11/06) 191 } 192 else { 193 appInfo = null; 194 } 195 } 196 197 /** 198 * タイマータスクのデーモン処理の開始ポイントです。 199 * 200 * @og.rev 3.5.2.0 (2003/10/20) vals 変数を、ローカルに移動 201 * @og.rev 3.5.4.8 (2004/02/23) タイムスタンプを、10回に1回とする。 202 * @og.rev 3.6.0.0 (2004/09/17) タイムスタンプを、24回に1回とする。 203 * @og.rev 3.6.1.0 (2005/01/05) tyr ~ catch を Exception から Throwable に変更。 204 * @og.rev 3.7.0.0 (2005/01/18) 複数同時デーモンでも、同一帳票IDは処理できない為、スキップします。 205 * @og.rev 3.7.0.4 (2005/03/18) エラー発生時に vals が null なら、HybsSystemException を throw する。 206 * @og.rev 3.7.1.1 (2005/05/31) GE50Access を使用して、DB登録を行います。 207 * @og.rev 3.8.0.0 (2005/06/07) EXCEL 取込時の完成フラグは、FG_DBIN とします。 208 * @og.rev 3.8.0.0 (2005/06/07) rc.execute() 実行結果を boolean ではなく、文字列(FGKAN_XX)で返します。 209 * @og.rev 3.8.5.0 (2006/03/06) EXCELファイル名に要求番号を使う場合は、帳票IDでの排他制御は不要。 210 * @og.rev 3.8.5.2 (2006/05/31) DEBUG 情報の強化 211 * @og.rev 3.8.6.0 (2006/06/30) タイマータスクがキャンセルされた場合の処理を追加(running フラグ) 212 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 213 * @og.rev 5.3.0.0 (2010/12/01) エラーハンドリングを修正 214 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 215 * @og.rev 5.7.0.4 (2013/11/29) listIdをGE50Accessに渡すようにする 216 * @og.rev 6.4.2.0 (2016/01/29) StringUtil#stringStackTrace(Throwable) を、ThrowUtil#ogStackTrace(String,Throwable) に置き換え。 217 * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 218 * @og.rev 6.4.3.3 (2016/03/04) Map#putIfAbsent で対応する。 219 * @og.rev 5.10.0.0 (2018/06/08) エラー時のメール送信判定にfgnomlのパラメータ設定を追加 220 */ 221 @Override 222 protected void startDaemon() { 223 if( loopCnt % LOOP_COUNTER == 0 ) { 224 loopCnt = 1; 225 System.out.println(); 226 System.out.print( toString() + " " + new Date() + " " ); 227 } 228 else { 229 System.out.print( "." ); 230 loopCnt++ ; 231 } 232 233 // 3.7.1.1 (2005/05/31) GE50Access を使用して、DB登録を行います。 234 GE50Access ge50 = null ; 235 236 String listId = null; // 6.4.3.1 (2016/02/12) vals をローカル化して、listId を大域化します。 237 try { 238 final String[][] vals = DBUtil.dbExecute( geSELECT,null,appInfo, DBID ); // 6.3.9.0 (2015/11/06) 239 if( vals != null && vals.length > 0 ) { 240 241 // 3.7.1.1 (2005/05/31) GE50Access を使用して、DB登録を行います。 242 // 毎回 オブジェクトを構築します。登録日付が初期化されます。 243 ge50 = new GE50Access( null,null,dmnNAME ) ; // 6.3.9.0 (2015/11/06) 244 245 if( rc == null ) { rc = new ReportProcessing(); } 246 // 3.8.6.0 (2006/06/30) タイマータスクがキャンセルされた場合の処理を追加(running フラグ) 247 for( int row=0; running && row<vals.length; row++ ) { // 6.4.3.1 (2016/02/12) 248 // 3.7.0.0 (2005/01/18) 使用中の帳票IDのチェックと、使用時の登録 249 final String systemId = vals[row][0] ; 250 final String ykno = vals[row][1] ; 251 listId = vals[row][3] ; // 6.4.3.1 (2016/02/12) 252 // 3.8.5.0 (2006/03/06) EXCELファイル名に要求番号を使う場合は、帳票IDでの排他制御は不要。 253 if( ! EXCEL_NAME_USE_YKNO ) { 254 // 6.4.3.3 (2016/03/04) Map#putIfAbsent で対応します。 255 // Map#putIfAbsent : 戻り値は、以前の値。追加有り、置換なし、削除なし 256 if( USE_LISTID.putIfAbsent( listId,"DUMMY" ) != null ) { continue; } // 使用中なら、飛ばす。 257 258 // 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 259 } 260 261 // デバッグ情報を出力します。 262 if( debug ) { 263 System.out.println(); 264 System.out.print( "[" + dmnNAME + "]:[" + ykno + "] START = " ); // 6.3.9.0 (2015/11/06) 265 System.out.println( new Date() ); 266 } 267 268 // 3.7.1.1 (2005/05/31) GE50Access を使用して、DB登録を行います。 269 ge50.setSystemId( systemId ); 270 ge50.setYkno( ykno ); 271 ge50.setFgNoMl( vals[row][8] ); // 5.10.0.0 (2018/06/08) ADD メール不要フラグ 272 ge50.updateGE50( GE50Access.FG_RUN ); 273 274 ge50.setListId( listId ); // 5.7.0.4 (2013/11/29) 275 276 // system_id,ykno,groupid,listid,joken,outdir,outfile,usrset 277 rc.setSystemId( systemId ); 278 rc.setYkno( ykno ); 279 rc.setGroupId( vals[row][2]); 280 rc.setListId( listId ); 281 rc.setJoken( vals[row][4]); 282 rc.setPrtId( prtID ); // 6.3.9.0 (2015/11/06) 283 rc.setOutDir( vals[row][5]); 284 rc.setOutFile( vals[row][6]); 285 rc.setDebug( debug ); // 3.8.5.0 (2006/03/06) DEBUGを追加。 286 287 // 3.8.0.0 (2005/06/07) 実行結果を boolean ではなく、文字列(FGKAN_XX)で返します。 288 String fgkan = rc.execute(); 289 if( fgkan == null ) { 290 fgkan = GE50Access.FG_ERR2 ; 291 final String errMsg = rc.getErrMsg(); 292 // 3.7.1.1 (2005/05/31) GE50Access を使用して、DB登録を行います。 293 ge50.insertErrorGE56( errMsg ); 294 } 295 296 // 3.7.1.1 (2005/05/31) GE50Access を使用して、DB登録を行います。 297 ge50.updateGE50( fgkan ); 298 299 rc.clear(); 300 // 3.8.5.0 (2006/03/06) EXCELファイル名に要求番号を使う場合は、帳票IDでの排他制御は不要。 301 if( ! EXCEL_NAME_USE_YKNO ) { 302 // 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 303 USE_LISTID.remove( listId ); 304 305 } 306 307 // デバッグ情報を出力します。 308 if( debug ) { 309 System.out.println(); 310 System.out.print( "[" + dmnNAME + "]:[" + ykno + "] END = " ); // 6.3.9.0 (2015/11/06) 311 System.out.println( new Date() ); 312 } 313 } 314 } 315 } 316 // 5.3.0.0 (2010/12/01) エラーハンドリングを修正 317 catch( final Throwable ex ) { // 3.6.1.0 (2005/01/05) 318 rc = null; 319 320 final String errMsg = ThrowUtil.ogStackTrace( ex ) ; // 6.4.2.0 (2016/01/29) 321 System.out.println( errMsg ); 322 LogWriter.log( errMsg ); 323 324 // 6.9.7.0 (2018/05/14) PMD These nested if statements could be combined 325// if( ! EXCEL_NAME_USE_YKNO ) { 326// // 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 327// if( listId != null ) { USE_LISTID.remove( listId ); } 328// } 329 if( ! EXCEL_NAME_USE_YKNO && listId != null ) { 330 // 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 331 USE_LISTID.remove( listId ); 332 } 333 334 // 3.7.1.1 (2005/05/31) GE50Access を使用して、DB登録を行います。 335 if( ge50 != null ) { 336 ge50.insertErrorGE56( errMsg ); 337 ge50.updateGE50( GE50Access.FG_ERR1 ); 338 } 339 // 6.4.3.1 (2016/02/12) 条件は異なるが、ほぼ、近いはず 340 else if( listId == null ) { 341 final String errMsg2 = "SQL=[" + geSELECT + "] , appInfo=[" + appInfo + "] , DBID=[" + DBID + "]"; 342 System.out.println( errMsg2 ); 343 LogWriter.log( errMsg2 ); 344 throw new HybsSystemException( errMsg + errMsg2 , ex ); 345 } 346 347 } 348 } 349 350 /** 351 * このタイマータスクのcancel() メソッドをオーバーライドします。 352 * HybsTimerTaskManager#cancelTask( int ) を実行します。 353 * 354 * @og.rev 3.8.5.3 (2006/06/30) 新規追加 355 * 356 * @return スケジュールされている 1 回以上実行されない場合に true 357 * @see java.util.TimerTask#cancel() 358 */ 359 @Override 360 public boolean cancel() { 361 running = false; 362 return super.cancel(); 363 } 364}