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