    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 * 各属性は、{&#064;XXXX} 変数が使用できます。
    035 * これは、ServletRequest から、xxxx をキーに値を取り出し,この変数に
    036 * 割り当てます。つまり、このxxxxをキーにリクエストすれば、
    037 * この変数に値をセットすることができます。
    038 *
    039 * http://localhost/query.jsp?KEY1=VLA1&amp;KEY2=VAL2
    040 *
    041 * のようなリクエストで、{&#064;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}