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.report;
017
018import org.opengion.hayabusa.common.HybsSystem;
019import org.opengion.fukurou.system.ThrowUtil ;                                  // 6.4.2.0 (2016/01/29)
020import org.opengion.fukurou.util.StringUtil;
021import org.opengion.fukurou.util.Shell;
022import org.opengion.fukurou.db.ApplicationInfo;
023import org.opengion.fukurou.db.DBUtil;
024import static org.opengion.fukurou.system.HybsConst.CR ;                                        // 6.1.0.0 (2014/12/26)
025import static org.opengion.fukurou.system.HybsConst.FS;                                 // 6.1.0.0 (2014/12/26) refactoring
026import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;              // 6.1.0.0 (2014/12/26) refactoring
027
028/**
029 * 【レポート出力】DBTableModelオブジェクトをレポート形式に返還するタグリブクラスです。
030 * このオブジェクトに、 データ(DBTableModel)と、コントローラ(DBTableReport クラス)を与えて、
031 * 外部からコントロールすることで、各種形式で データ(DBTableModel)を表示させることが
032 * 可能です。
033 *
034 * 各属性は、{@XXXX} 変数が使用できます。
035 * これは、ServletRequest から、xxxx をキーに値を取り出し,この変数に
036 * 割り当てます。つまり、このxxxxをキーにリクエストすれば、
037 * この変数に値をセットすることができます。
038 *
039 * http://localhost/query.jsp?KEY1=VLA1&KEY2=VAL2
040 *
041 * のようなリクエストで、{@KEY1} とすれば、 VAL1 がセットされます。
042 *
043 * @og.group 帳票システム
044 *
045 * @version  4.0
046 * @author   Kazuhiko Hasegawa
047 * @since    JDK5.0,
048 */
049public class ReportPrint {
050        // 3.6.1.0 (2005/01/05) Shell の タイムアウトを設定
051        private final int TIMEOUT = HybsSystem.sysInt( "REPORT_DAEMON_TIMEOUT" );
052
053        private final StringBuilder errMsg = new StringBuilder( BUFFER_MIDDLE );
054
055        private final String    SYSTEM_ID       ;
056        private final String    YKNO            ;
057        private final String    PRTID           ;
058        private       String    prtNM           ;               // 6.3.9.0 (2015/11/06) Variables should start with a lowercase character(PMD)
059        private final String    programFile     ;
060        private final String    htmlDir         ;
061        private final String    modelFile       ;
062        private final String    pdfFile         ;
063        private final String    DMN_GRP         ;               // 3.8.0.5 (2005/08/26)
064        private final boolean   DEBUG           ;               // 3.8.5.0 (2006/03/06) デバッグ用のフラグを追加
065
066        private String          shellCmd                ;
067
068        // GE55 のプリンタ名を取得するSQL文です。
069        // 4.0.0 (2005/01/31) 共有 system_id を、考慮
070        private static final String GE55_SELECT =
071                "SELECT PRTNM,SYSTEM_ID" +
072                " FROM GE55" +
073                " WHERE FGJ = '1'" +
074                " AND  SYSTEM_ID IN (?,'**')" +
075                " AND  PRTID = ?" ;
076
077        private static final int GE55_PRTNM             = 0;
078        private static final int GE55_SYSTEM_ID = 1;
079
080        /** コネクションにアプリケーション情報を追記するかどうか指定 */
081        public static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
082
083        // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
084        private final ApplicationInfo appInfo;
085        private final String DBID = HybsSystem.sys( "RESOURCE_DBID" );          // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応
086
087        /**
088         * コンストラクター
089         *
090         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
091         *
092         * @param system_id システムID
093         * @param ykno 要求番号
094         * @param prtId プリンターID
095         * @param prgFile 実行プログラムID
096         * @param inDir レポート入力ディレクトリ
097         * @param mdlFile テンポラリーファイル
098         * @param outFile 出力ファイル名
099         * @param dmnGrp  デーモングループ
100         * @param debug デバッグフラグ
101         */
102        public ReportPrint( final String system_id, final String ykno, final String prtId,
103                                                final String prgFile,final String inDir,final String mdlFile,
104                                                final String outFile,final String dmnGrp,final boolean debug ) {
105                SYSTEM_ID       = system_id;
106                YKNO            = ykno;
107                PRTID           = prtId;
108                programFile     = prgFile ;
109                htmlDir         = inDir ;
110                modelFile       = mdlFile ; // 4.0.1.0 (2007/12/18)
111                pdfFile         = outFile ;
112                DMN_GRP         = dmnGrp;                               // 3.8.0.5 (2005/08/26)
113                DEBUG           = debug;
114
115                // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
116                if( USE_DB_APPLICATION_INFO ) {
117                        appInfo = new ApplicationInfo();
118                        // ユーザーID,IPアドレス,ホスト名
119                        appInfo.setClientInfo( SYSTEM_ID,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
120                        // 画面ID,操作,プログラムID
121                        appInfo.setModuleInfo( "ReportPrint",YKNO,PRTID );
122                }
123                else {
124                        appInfo = null;
125                }
126        }
127
128        /**
129         * レポート出力処理を実行します。
130         *
131         * @og.rev 6.4.2.0 (2016/01/29) StringUtil#stringStackTrace(Throwable) を、ThrowUtil#ogStackTrace(Throwable) に置き換え。
132         *
133         * @return 結果 [true:正常/false:異常]
134         */
135        public boolean execute() {
136                System.out.print( "ReportPrint Started ... " );
137                boolean flag ;
138
139                try {
140                        flag = initialDataSet();
141                        if( flag ) { System.out.print( "INIT," ); }
142
143                        if( flag ) {
144                                flag = makeShellCommand();
145                                if( flag ) { System.out.print( "SHELL," ); }
146                        }
147
148                        if( flag ) {
149                                flag = programRun();
150                                if( flag ) { System.out.print( "RUN," ); }
151                                // 3.8.5.3 (2006/06/30) 帳票処理実行時エラーの再実行
152        //                      else {
153        //                              System.out.println();
154        //                              System.out.println( "帳票印刷時にエラーが発生しました。リトライします。" );
155        //                              System.out.println( "YKNO=[" + YKNO + "],PRTID=[" + PRTID + "],DMN_GRP=[" + DMN_GRP + "]" );
156        //                              System.out.println();
157        //                              flag = programRun();
158        //                              if( flag ) { System.out.print( "RUN 2," ); }
159        //                              else {
160        //                                      System.out.println( "帳票印刷リトライに失敗しました。YKNO=[" + YKNO + "]" );
161        //                              }
162        //                      }
163                        }
164                }
165                catch( final RuntimeException ex ) {
166                        errMsg.append( "ReportPrint Execute Error! " ).append( CR ) 
167                                .append( "==============================" ).append( CR )
168                                .append( ThrowUtil.ogStackTrace( ex ) ).append( CR ) ;                                  // 6.4.2.0 (2016/01/29)
169                        flag = false;
170                }
171
172                System.out.println( "End." );
173                return flag ;
174        }
175
176        /**
177         * 初期データセットを行います。
178         * ここでは、GE55 テーブルより必要な情報を取得します。
179         *
180         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
181         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
182         *
183         * @return 結果 [true:正常/false:異常]
184         */
185        private boolean initialDataSet() {
186                if( PRTID == null ) {
187                        errMsg.append( "PRTID columns does not exist in GE55 table." ).append( CR )
188                                .append( "==============================" ).append( CR )
189                                .append( "SYSTEM_ID=[" ).append( SYSTEM_ID )
190                                .append( "] , PRTID=[" ).append( PRTID     ).append( ']' )              // 6.0.2.5 (2014/10/31) char を append する。
191                                .append( CR );
192                        return false;
193                }
194
195                final String[] args = new String[] { SYSTEM_ID,PRTID };
196                // prtnm,system_id
197                final String[][] vals = DBUtil.dbExecute( GE55_SELECT,args,appInfo, DBID );     // 5.5.5.1 (2012/08/07)
198                if( vals == null || vals.length == 0 ) {
199                        errMsg.append( "Data does not exist in GE55 table." ).append( CR )
200                                .append( "==============================" ).append( CR )
201                                .append( "SYSTEM_ID=[" ).append( SYSTEM_ID )
202                                .append( "] , PRTID=[" ).append( PRTID     ).append( ']' )              // 6.0.2.5 (2014/10/31) char を append する。
203                                .append( CR );
204                        return false;
205                }
206
207                int row = 0;
208                // 検索結果が複数帰ったとき、SYSTEM_ID が 指定されている方のデータ(行)を採用する。
209                for( int i=0; i<vals.length; i++ ) {
210                        if( SYSTEM_ID.equalsIgnoreCase( vals[i][GE55_SYSTEM_ID] ) ) { row = i; break; }
211                }
212
213                prtNM = StringUtil.nval( vals[row][GE55_PRTNM],prtNM );         // 6.3.9.0 (2015/11/06) Variables should start with a lowercase character(PMD)
214
215                if( DEBUG ) {
216                        System.out.println( "SYSTEM_ID   =" + SYSTEM_ID   );
217                        System.out.println( "YKNO        =" + YKNO        );
218                        System.out.println( "PRTID       =" + PRTID       );
219                        System.out.println( "PRTNM       =" + prtNM       );    // 6.3.9.0 (2015/11/06) Variables should start with a lowercase character(PMD)
220                        System.out.println( "programFile =" + programFile );
221                        System.out.println( "htmlDir     =" + htmlDir     );
222                        System.out.println( "pdfFile     =" + pdfFile     );
223                        System.out.println( "DMN_GRP     =" + DMN_GRP     );
224                        System.out.println( "GE55_SELECT =" + GE55_SELECT );
225                }
226
227                return true;
228        }
229
230        /**
231         * シェルコマンドの文字列を作成します。
232         *
233         * @og.rev 3.8.0.5 (2005/08/26) 引数にデーモングループを追加
234         * @og.rev 3.8.0.8 (2005/10/03) デーモングループのデフォルト値設定
235         * @og.rev 4.0.1.0 (2007/12/18) 帳票のテンポラリーファイルを追加
236         *
237         * @return 結果 [true:正常/false:異常]
238         */
239        private boolean makeShellCommand() {
240
241                // 6.0.2.5 (2014/10/31) char を append する。
242                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
243                        .append( programFile ).append( ' ' )                                            // 実行するコマンド
244                        .append( '"' ).append( htmlDir ).append( FS )                           // 入力HTMLファイル
245                        .append( YKNO ).append( "_*.html\" " )                                          // 入力HTMLファイル
246                        .append( '"' ).append( prtNM ).append( "\" " );                         // プリンタ名 // 6.3.9.0 (2015/11/06) Variables should start with a lowercase character(PMD)
247
248                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
249                if( pdfFile == null ) {
250                        // ダミーファイルを指定する必要がある。
251                        buf.append( '"' ).append( htmlDir ).append( FS )
252                                .append( YKNO ).append( ".xls\" " );            // ダミー出力ファイル
253                }
254                else {
255                        buf.append( '"' ).append( pdfFile ).append( "\" " );            // PDFファイル名
256                }
257
258                // 3.8.5.0 (2006/03/06) EXCELをオープンするファイル名に要求番号を使う
259                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
260                if( modelFile == null ) { // 4.0.1.0 (2007/12/18)
261                        buf.append( "DMY_MDL " );                                       // ダミーモデルファイル名(4)
262                }
263                else {
264                        buf.append( modelFile ).append( ' ' );          // モデルファイル名(4)
265                }
266
267                // 3.8.5.0 (2006/03/06) DMN_GRPは必須
268                buf.append( DMN_GRP ).append( ' ' )                     // デーモングループ             // 6.0.2.5 (2014/10/31) char を append する。
269                        .append( PRTID );               // プリンタID(この名前.pdf でPDFファイルが作成される。)
270
271                shellCmd = buf.toString();
272                System.out.println( CR + shellCmd + CR );
273
274                return true;
275        }
276
277        /**
278         * 実際のレポート出力処理を行います。
279         *
280         * @og.rev 3.1.9.0 (2003/05/16) Shell への stdout と stderr の取得設定は廃止。ShellTag では、有効。
281         * @og.rev 3.6.1.0 (2005/01/05) Shell の タイムアウトを設定
282         *
283         * @return 結果 [true:正常/false:異常]
284         */
285        private boolean programRun() {
286                final Shell shell = new Shell();
287                shell.setCommand( shellCmd,true );              // BATCHプロセスで実行する
288                shell.setWait( true );                                  // プロセスの終了を待つ
289                shell.setTimeout( TIMEOUT );                    // 3.6.1.0 (2005/01/05) Shell の タイムアウトを設定
290
291                final int rtnCode = shell.exec();                               // 0 は正常終了を示す
292
293                if( rtnCode != 0 ) {
294                        errMsg.append( "Shell Command exequte Error." ).append( CR );
295                        errMsg.append( "==============================" ).append( CR );
296                        errMsg.append( shellCmd ).append( CR );
297                        errMsg.append( shell.getStdoutData() ).append( CR );
298                        errMsg.append( shell.getStderrData() ).append( CR );
299                        errMsg.append( CR );
300                        return false;
301                }
302
303                return true;
304        }
305
306        /**
307         * エラーが存在した場合に、エラーメッセージを返します。
308         *
309         * @return エラーメッセージ String
310         * @og.rtnNotNull
311         */
312        public String getErrMsg() {
313                return errMsg.toString();
314        }
315}