    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    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}