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