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    BASE_SYS_ID = "**" ;    // 7.2.6.0 (2020/06/30) ベースシステムID
067
068        private String          shellCmd                ;
069
070        // GE55 のプリンタ名を取得するSQL文です。
071        // 4.0.0 (2005/01/31) 共有 system_id を、考慮
072        private static final String GE55_SELECT =
073                "SELECT PRTNM,SYSTEM_ID" +
074                " FROM GE55" +
075                " WHERE FGJ = '1'" +
076                " AND  SYSTEM_ID IN (?,'**')" +
077                " AND  PRTID = ?" ;
078
079        // GE55 のプリンタ名を取得するSQL文です。
080        // 7.2.6.1 (2020/07/17) "**"以外にベースとなるSYSTEM_ID(RESOURCE_BASE_SYSTEM_ID)設定の対応
081        // 7.2.8.0 (2020/09/04) RESOURCE_BASE_SYSTEM_ID 対応で、帳票系は難しいので対応しません
082//      private static final String GE55_SELECT =
083//              "SELECT PRTNM,SYSTEM_ID"
084//              + " from ("
085//              + "  select 0 as SNO,B.* from GE55 B where SYSTEM_ID='**' and PRTID=? and FGJ='1'"      // エンジン共通
086//              + "  union all"
087//              + "  select 1 as SNO,B.* from GE55 B where SYSTEM_ID=? and PRTID=? and FGJ='1'" // RESOURCE_BASE_SYSTEM_ID
088//              + "  union all"
089//              + "  select 2 as SNO,B.* from GE55 B where SYSTEM_ID=? and PRTID=? and FGJ='1'" // 最上位ののSYSTEM_ID
090//              + " ) A"
091//              + " order by SNO,SYSTEM_ID" ;
092
093        private static final int GE55_PRTNM             = 0;
094//      private static final int GE55_SYSTEM_ID = 1;
095
096        /** コネクションにアプリケーション情報を追記するかどうか指定 */
097        public static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
098
099        // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
100        private final ApplicationInfo appInfo;
101        private final String DBID = HybsSystem.sys( "RESOURCE_DBID" );          // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応
102
103        /**
104         * コンストラクター
105         *
106         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
107         *
108         * @param system_id システムID
109         * @param ykno 要求番号
110         * @param prtId プリンターID
111         * @param prgFile 実行プログラムID
112         * @param inDir レポート入力ディレクトリ
113         * @param mdlFile テンポラリーファイル
114         * @param outFile 出力ファイル名
115         * @param dmnGrp  デーモングループ
116         * @param debug デバッグフラグ
117         */
118        public ReportPrint( final String system_id, final String ykno, final String prtId,
119                                                final String prgFile,final String inDir,final String mdlFile,
120                                                final String outFile,final String dmnGrp,final boolean debug ) {
121                SYSTEM_ID       = system_id;
122                YKNO            = ykno;
123                PRTID           = prtId;
124                programFile     = prgFile ;
125                htmlDir         = inDir ;
126                modelFile       = mdlFile ; // 4.0.1.0 (2007/12/18)
127                pdfFile         = outFile ;
128                DMN_GRP         = dmnGrp;                               // 3.8.0.5 (2005/08/26)
129                DEBUG           = debug;
130
131                // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
132                if( USE_DB_APPLICATION_INFO ) {
133                        appInfo = new ApplicationInfo();
134                        // ユーザーID,IPアドレス,ホスト名
135                        appInfo.setClientInfo( SYSTEM_ID,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
136                        // 画面ID,操作,プログラムID
137                        appInfo.setModuleInfo( "ReportPrint",YKNO,PRTID );
138                }
139                else {
140                        appInfo = null;
141                }
142        }
143
144        /**
145         * レポート出力処理を実行します。
146         *
147         * @og.rev 6.4.2.0 (2016/01/29) StringUtil#stringStackTrace(Throwable) を、ThrowUtil#ogStackTrace(Throwable) に置き換え。
148         *
149         * @return 結果 [true:正常/false:異常]
150         */
151        public boolean execute() {
152                System.out.print( "ReportPrint Started ... " );
153                boolean flag ;
154
155                try {
156                        flag = initialDataSet();
157                        if( flag ) { System.out.print( "INIT," ); }
158
159                        if( flag ) {
160                                flag = makeShellCommand();
161                                if( flag ) { System.out.print( "SHELL," ); }
162                        }
163
164                        if( flag ) {
165                                flag = programRun();
166                                if( flag ) { System.out.print( "RUN," ); }
167                                // 3.8.5.3 (2006/06/30) 帳票処理実行時エラーの再実行
168        //                      else {
169        //                              System.out.println();
170        //                              System.out.println( "帳票印刷時にエラーが発生しました。リトライします。" );
171        //                              System.out.println( "YKNO=[" + YKNO + "],PRTID=[" + PRTID + "],DMN_GRP=[" + DMN_GRP + "]" );
172        //                              System.out.println();
173        //                              flag = programRun();
174        //                              if( flag ) { System.out.print( "RUN 2," ); }
175        //                              else {
176        //                                      System.out.println( "帳票印刷リトライに失敗しました。YKNO=[" + YKNO + "]" );
177        //                              }
178        //                      }
179                        }
180                }
181                catch( final RuntimeException ex ) {
182                        errMsg.append( "ReportPrint Execute Error! " ).append( CR )
183                                .append( "==============================" ).append( CR )
184                                .append( ThrowUtil.ogStackTrace( ex ) ).append( CR ) ;                                  // 6.4.2.0 (2016/01/29)
185                        flag = false;
186                }
187
188                System.out.println( "End." );
189                return flag ;
190        }
191
192        /**
193         * 初期データセットを行います。
194         * ここでは、GE55 テーブルより必要な情報を取得します。
195         *
196         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
197         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
198         * @og.rev 7.2.6.1 (2020/07/17) "**"以外にベースとなるSYSTEM_ID(RESOURCE_BASE_SYSTEM_ID)設定の対応
199         * @og.rev 7.2.8.0 (2020/09/04) RESOURCE_BASE_SYSTEM_ID 対応で、帳票系は難しいので対応しません
200         *
201         * @return 結果 [true:正常/false:異常]
202         */
203        private boolean initialDataSet() {
204        //      final String baseSystemId = HybsSystem.sys( "RESOURCE_BASE_SYSTEM_ID", false );
205        //      BASE_SYS_ID = StringUtil.isEmpty( baseSystemId ) ? "**" : baseSystemId ;
206
207                if( PRTID == null ) {
208                        errMsg.append( "PRTID columns does not exist in GE55 table." ).append( CR )
209                                .append( "==============================" ).append( CR )
210                                .append( "SYSTEM_ID=[" ).append( SYSTEM_ID )
211                                .append( "] , PRTID=[" ).append( PRTID     ).append( ']' )              // 6.0.2.5 (2014/10/31) char を append する。
212                                .append( CR );
213                        return false;
214                }
215
216                // 7.2.6.1 (2020/07/17) "**"以外にベースとなるSYSTEM_ID(RESOURCE_BASE_SYSTEM_ID)設定の対応
217                final String[] args = new String[] { SYSTEM_ID,PRTID };
218        // 7.2.8.0 (2020/09/04) RESOURCE_BASE_SYSTEM_ID 対応で、帳票系は難しいので対応しません
219        //      final String[] args = new String[] { PRTID,BASE_SYS_ID,PRTID,SYSTEM_ID,PRTID };
220                // prtnm,system_id
221                final String[][] vals = DBUtil.dbExecute( GE55_SELECT,args,appInfo, DBID );     // 5.5.5.1 (2012/08/07)
222                if( vals == null || vals.length == 0 ) {
223                        errMsg.append( "Data does not exist in GE55 table." ).append( CR )
224                                .append( "==============================" ).append( CR )
225                                .append( "SYSTEM_ID=[" ).append( SYSTEM_ID )
226                                .append( "] , PRTID=[" ).append( PRTID     ).append( ']' )              // 6.0.2.5 (2014/10/31) char を append する。
227                                .append( CR );
228                        return false;
229                }
230
231                // 検索結果が複数帰ったとき、SYSTEM_ID が 指定されている方のデータ(行)を採用する。
232                // 7.2.6.1 (2020/07/17) 一番最後のデータを採用する。
233                final int row = vals.length;
234//              int row = 0;
235//              for( int i=0; i<vals.length; i++ ) {
236//                      if( SYSTEM_ID.equalsIgnoreCase( vals[i][GE55_SYSTEM_ID] ) ) { row = i; break; }
237//              }
238
239                prtNM = StringUtil.nval( vals[row][GE55_PRTNM],prtNM );         // 6.3.9.0 (2015/11/06) Variables should start with a lowercase character(PMD)
240
241                if( DEBUG ) {
242                        System.out.println( "SYSTEM_ID   =" + SYSTEM_ID   );
243                        System.out.println( "YKNO        =" + YKNO        );
244                        System.out.println( "PRTID       =" + PRTID       );
245                        System.out.println( "PRTNM       =" + prtNM       );    // 6.3.9.0 (2015/11/06) Variables should start with a lowercase character(PMD)
246                        System.out.println( "programFile =" + programFile );
247                        System.out.println( "htmlDir     =" + htmlDir     );
248                        System.out.println( "pdfFile     =" + pdfFile     );
249                        System.out.println( "DMN_GRP     =" + DMN_GRP     );
250                        System.out.println( "GE55_SELECT =" + GE55_SELECT );
251                }
252
253                return true;
254        }
255
256        /**
257         * シェルコマンドの文字列を作成します。
258         *
259         * @og.rev 3.8.0.5 (2005/08/26) 引数にデーモングループを追加
260         * @og.rev 3.8.0.8 (2005/10/03) デーモングループのデフォルト値設定
261         * @og.rev 4.0.1.0 (2007/12/18) 帳票のテンポラリーファイルを追加
262         *
263         * @return 結果 [true:正常/false:異常]
264         */
265        private boolean makeShellCommand() {
266
267                // 6.0.2.5 (2014/10/31) char を append する。
268                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
269                        .append( programFile ).append( ' ' )                                            // 実行するコマンド
270                        .append( '"' ).append( htmlDir ).append( FS )                           // 入力HTMLファイル
271                        .append( YKNO ).append( "_*.html\" " )                                          // 入力HTMLファイル
272                        .append( '"' ).append( prtNM ).append( "\" " );                         // プリンタ名 // 6.3.9.0 (2015/11/06) Variables should start with a lowercase character(PMD)
273
274                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
275                if( pdfFile == null ) {
276                        // ダミーファイルを指定する必要がある。
277                        buf.append( '"' ).append( htmlDir ).append( FS )
278                                .append( YKNO ).append( ".xls\" " );            // ダミー出力ファイル
279                }
280                else {
281                        buf.append( '"' ).append( pdfFile ).append( "\" " );            // PDFファイル名
282                }
283
284                // 3.8.5.0 (2006/03/06) EXCELをオープンするファイル名に要求番号を使う
285                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
286                if( modelFile == null ) { // 4.0.1.0 (2007/12/18)
287                        buf.append( "DMY_MDL " );                                       // ダミーモデルファイル名(4)
288                }
289                else {
290                        buf.append( modelFile ).append( ' ' );          // モデルファイル名(4)
291                }
292
293                // 3.8.5.0 (2006/03/06) DMN_GRPは必須
294                buf.append( DMN_GRP ).append( ' ' )                     // デーモングループ             // 6.0.2.5 (2014/10/31) char を append する。
295                        .append( PRTID );               // プリンタID(この名前.pdf でPDFファイルが作成される。)
296
297                shellCmd = buf.toString();
298                System.out.println( CR + shellCmd + CR );
299
300                return true;
301        }
302
303        /**
304         * 実際のレポート出力処理を行います。
305         *
306         * @og.rev 3.1.9.0 (2003/05/16) Shell への stdout と stderr の取得設定は廃止。ShellTag では、有効。
307         * @og.rev 3.6.1.0 (2005/01/05) Shell の タイムアウトを設定
308         *
309         * @return 結果 [true:正常/false:異常]
310         */
311        private boolean programRun() {
312                final Shell shell = new Shell();
313                shell.setCommand( shellCmd,true );              // BATCHプロセスで実行する
314                shell.setWait( true );                                  // プロセスの終了を待つ
315                shell.setTimeout( TIMEOUT );                    // 3.6.1.0 (2005/01/05) Shell の タイムアウトを設定
316
317                final int rtnCode = shell.exec();                               // 0 は正常終了を示す
318
319                if( rtnCode != 0 ) {
320                        errMsg.append( "Shell Command exequte Error." ).append( CR );
321                        errMsg.append( "==============================" ).append( CR );
322                        errMsg.append( shellCmd ).append( CR );
323                        errMsg.append( shell.getStdoutData() ).append( CR );
324                        errMsg.append( shell.getStderrData() ).append( CR );
325                        errMsg.append( CR );
326                        return false;
327                }
328
329                return true;
330        }
331
332        /**
333         * エラーが存在した場合に、エラーメッセージを返します。
334         *
335         * @return エラーメッセージ String
336         * @og.rtnNotNull
337         */
338        public String getErrMsg() {
339                return errMsg.toString();
340        }
341}