    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.report2;
    017
    018import java.io.File;
    019import java.util.Arrays;
    020
    021import org.opengion.fukurou.db.DBFunctionName;
    022import org.opengion.fukurou.db.DBUtil;
    023import org.opengion.fukurou.mail.MailTX;
    024import org.opengion.fukurou.util.ApplicationInfo;
    025import org.opengion.fukurou.util.LogWriter;
    026import org.opengion.fukurou.util.StringUtil;
    027import org.opengion.fukurou.util.UnicodeCorrecter;
    028import org.opengion.hayabusa.common.HybsSystem;
    029import org.opengion.hayabusa.db.DBTableModel;
    030import org.opengion.hayabusa.db.DBTableModelUtil;
    031import org.opengion.hayabusa.resource.ResourceFactory;
    032import org.opengion.hayabusa.resource.ResourceManager;
    033
    034/**
    035 * DBからキューを作成するためのクラスです。
    036 * キューはGE5xテーブルから作成されます。
    037 *
    038 * キュー生成時点(処理スレッドにスタックした時点)では、帳票データのテーブルモデルは作成されません。
    039 * 帳票データは、各スレッドからset()メソッドを呼び出したタイミングで生成されます。
    040 *
    041 * 処理開始及び、完了のステータスは、GE50の完成フラグに更新されます。
    042 * また、エラー発生時のメッセージは、GE56に更新されます。
    043 *
    044 * @og.group 帳票システム
    045 *
    046 * @version  4.0
    047 * @author   Hiroki.Nakamura
    048 * @since    JDK1.6
    049 */
    050public final class QueueManager_DB implements QueueManager {
    051
    052        /** コネクションにアプリケーション情報を追記するかどうか指定 */
    053        private static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
    054
    055        /** アプリケーション情報 */
    056        private static final ApplicationInfo appInfo;
    057        static {
    058                if( USE_DB_APPLICATION_INFO ) {
    059                        appInfo = new ApplicationInfo();
    060                        // ユーザーID,IPアドレス,ホスト名
    061                        appInfo.setClientInfo( "ReportDaemon", HybsSystem.HOST_ADRS, HybsSystem.HOST_NAME );
    062                        // 画面ID,操作,プログラムID
    063                        appInfo.setModuleInfo( "ReportDaemon", "QueueManager", "QueueManager" );
    064                }
    065                else {
    066                        appInfo = null;
    067                }
    068        }
    069
    070        private static final String DBID = HybsSystem.sys( "RESOURCE_DBID" );           // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応
    071
    072//      private static final String SQL_SELECT_GE50 =
    073//              "SELECT A.SYSTEM_ID, A.YKNO, A.LISTID, A.OUT_DIR, A.OUT_FILE, A.PDF_PASSWD"
    074//              + ", B.LANG, B.FGRUN, B.DMN_GRP "
    075//              + ", C.MODELDIR, C.MODELFILE, D.PRTNM, C.FGLOCAL, C.FGCUT, C.BSQL, C.HSQL, C.FSQL "
    076//              + "FROM GE50 A, GE53 B, GE54 C, GE55 D "
    077//              + "WHERE A.FGKAN='1' "
    078//              + "AND A.SYSTEM_ID = B.SYSTEM_ID AND A.JOKEN = B.JOKEN "
    079//              + "AND A.SYSTEM_ID = C.SYSTEM_ID AND A.LISTID = C.LISTID "
    080//              + "AND B.SYSTEM_ID = D.SYSTEM_ID AND B.PRTID = D.PRTID ORDER BY"
    081//              + HybsSystem.sys( "REPORT_DAEMON_ORDER_BY" );
    082
    083        // 4.3.0.0 (2008/07/18) PDF出力時に出力先マスタは不要のためGE55は外部結合に変更
    084//      private static final String SQL_SELECT_GE50 =
    085//              "SELECT A.SYSTEM_ID, A.YKNO, A.LISTID, A.OUT_DIR, A.OUT_FILE, A.PDF_PASSWD"
    086//              + ", B.LANG, B.FGRUN, B.DMN_GRP "
    087//              + ", C.MODELDIR, C.MODELFILE, D.PRTNM, C.FGLOCAL, C.FGCUT, C.BSQL, C.HSQL, C.FSQL "
    088//              + "FROM GE50 A, GE53 B, GE54 C, GE55 D "
    089//              + "WHERE A.FGKAN='1' "
    090//              + "AND A.SYSTEM_ID = B.SYSTEM_ID AND A.JOKEN = B.JOKEN "
    091//              + "AND A.SYSTEM_ID = C.SYSTEM_ID AND A.LISTID = C.LISTID "
    092//              + "AND B.SYSTEM_ID = D.SYSTEM_ID(+) AND B.PRTID = D.PRTID(+) ORDER BY"
    093//              + HybsSystem.sys( "REPORT_DAEMON_ORDER_BY" );
    094
    095        // 4.3.7.0 (2009/06/01) HSQLDB対応
    096//      private static final String CON = DBFunctionName.getFunctionName( "CON", ConnectionFactory.getDBFullName( null ) );
    097        // 5.1.4.0 (2010/03/01) データベース名 でなく、DBID名で検索するように変更します。
    098        private static final String CON = DBFunctionName.getFunctionName( "CON", null );
    099
    100        // 5.2.0.0 (2010/09/01) Ver4互換モード対応
    101        private static final String OUT_FILE = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "OUTFILE" : "OUT_FILE";
    102        private static final String OUT_DIR = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "OUTDIR" : "OUT_DIR";
    103
    104        // 4.3.3.6 (2008/11/15) マルチサーバ対応追加(GE12から処理対象デーモングループ取得)
    105        // 4.3.7.0 (2009/06/01) HSQLDB対応
    106        // 5.2.0.0 (2010/09/01) Ver4互換モード対応
    107        // 5.4.2.0 (2011/12/26) PRTID,PRGDIR,PRGFILE取得
    108        // 5.9.2.2 (2015/11/20) GROUPID追加
    109        // 5.10.0.0 (2018/06/08) FGNOML(メール不要フラグ)を追加
    110        private static final String SQL_SELECT_GE50 =
    111//              "SELECT A.SYSTEM_ID, A.YKNO, A.LISTID, A.OUT_DIR, A.OUT_FILE, A.PDF_PASSWD"
    112                "SELECT A.SYSTEM_ID, A.YKNO, A.LISTID, A."+OUT_DIR+", A."+OUT_FILE+", A.PDF_PASSWD"
    113                + ", B.LANG, B.FGRUN, B.DMN_GRP "
    114                + ", C.MODELDIR, C.MODELFILE, D.PRTNM, C.FGLOCAL, C.FGCUT, C.BSQL, C.HSQL, C.FSQL "
    115                + " ,B.PRTID, B.PRGDIR, B.PRGFILE "
    116                + " ,A.GROUPID " // 5.9.2.2 (2015/11/20)
    117                + " ,C.FGNOML " // 5.10.0.0 (2018/06/08)
    118//              + "FROM GE50 A, GE53 B, GE54 C, GE55 D "
    119                + "FROM GE50 A "
    120                + "INNER JOIN GE53 B "
    121                + "ON A.SYSTEM_ID = B.SYSTEM_ID AND A.JOKEN = B.JOKEN "
    122                + "INNER JOIN GE54 C "
    123                + "ON A.SYSTEM_ID = C.SYSTEM_ID AND A.LISTID = C.LISTID "
    124                + "LEFT OUTER JOIN GE55 D "
    125                + "ON B.SYSTEM_ID = D.SYSTEM_ID AND B.PRTID = D.PRTID "
    126                + "WHERE A.FGKAN='1' "
    127                + "AND EXISTS ( SELECT 'X' FROM GE12 E "
    128                +                               "WHERE  E.FGJ                           ='1' "
    129                +                               "AND            E.SYSTEM_ID     = '"
    130                +                               HybsSystem.sys( "SYSTEM_ID" )
    131                +                               "' "
    132                +                               "AND            E.CONTXT_PATH   = '"
    133                +                               HybsSystem.sys( "HOST_URL" )
    134                +                               "' "
    135                +                               "AND            E.PARAM_ID              LIKE 'REPORT2_HANDLE_DAEMON_%' "
    136                +                               "AND            E.PARAM                 = 'RUN_'" + CON + "A.SYSTEM_ID" + CON + "'_'" + CON + "B.DMN_GRP"
    137                +                       ") "
    138//              + "AND A.SYSTEM_ID = B.SYSTEM_ID AND A.JOKEN = B.JOKEN "
    139//              + "AND A.SYSTEM_ID = C.SYSTEM_ID AND A.LISTID = C.LISTID "
    140//              + "AND B.SYSTEM_ID = D.SYSTEM_ID(+) AND B.PRTID = D.PRTID(+) ORDER BY"
    141                + "ORDER BY "
    142                + HybsSystem.sys( "REPORT_DAEMON_ORDER_BY" );
    143
    144        // 5.1.2.0 (2010/01/01) ページ数、データ数をGE50に更新する。
    145        private static final String SQL_UPDATE_GE50 =
    146//              "UPDATE GE50 SET FGKAN = ?, DMN_NAME = ?, DMN_HOST = ? ,DYUPD = ? WHERE SYSTEM_ID = ? AND YKNO = ?";
    147                "UPDATE GE50 SET FGKAN = ?, DMN_NAME = ?, DMN_HOST = ?, SUDATA = ?, SUPAGE = ?, DYUPD = ? WHERE SYSTEM_ID = ? AND YKNO = ?";
    148
    149        private static final String SQL_INSERT_GE56 =
    150                "INSERT INTO GE56 ( FGJ, SYSTEM_ID, YKNO, ERRMSG, DYSET, DYUPD, USRSET, USRUPD, PGUPD ) "
    151                + " VALUES ( '1', ?, ? ,? ,? ,? ,? ,? ,? )" ;
    152
    153        private static final int STATUS_COMPLETE        = 2;
    154        private static final int STATUS_EXECUTE         = 3;
    155        private static final int STATUS_ERROR           = 8;
    156
    157        private static QueueManager manager = new QueueManager_DB();
    158
    159        /**
    160         * インスタンスの生成を禁止します。
    161         */
    162        private QueueManager_DB() {}
    163
    164        /**
    165         * インスタンスを返します。
    166         *
    167         * @return      帳票処理キューの管理マネージャ
    168         */
    169        public static QueueManager getInstance() {
    170                return manager;
    171        }
    172
    173
    174        /**
    175         * 帳票処理キューを作成します。
    176         *
    177         * @og.rev 4.3.0.0 (2008/07/15) スレッドIDにシステムIDを付加します。
    178         * @og.rev 5.1.2.0 (2010/01/01) HSQL,FSQL,BSQLのセットを廃止します。(このクラス内でデータを直接分割)
    179         * @og.rev 5.4.3.0 (2011/12/26) PRTIDの取得
    180         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
    181         * @og.rev 5.10.0.0 (2018/06/08) FGNOML対応
    182         * @og.rev 5.10.9.0 (2019/03/01) クラウドストレージ対応を追加。
    183         * @og.rev 5.10.9.2 (2019/03/15) 5.10.9.0の対応修正
    184         */
    185        public synchronized void create() {
    186                // キューをスタックするまでの例外は、ScheduleTagでcatchされデーモンがスリープする。
    187//              String[][] ge50vals = DBUtil.dbExecute( SQL_SELECT_GE50, new String[0], appInfo );
    188                String[][] ge50vals = DBUtil.dbExecute( SQL_SELECT_GE50, new String[0], appInfo, DBID );        // 5.5.5.1 (2012/08/07)
    189
    190                for( int i=0; i<ge50vals.length; i++ ) {
    191                        ExecQueue queue = new ExecQueue();
    192                        queue.setSystemId( ge50vals[i][0] );
    193                        queue.setYkno( ge50vals[i][1] );
    194                        queue.setListId( ge50vals[i][2] );
    195                        // queue.setOutputName( new File( ge50vals[i][3] ).getAbsolutePath() + File.separator + ge50vals[i][4] );
    196                        // 5.10.9.0 (2019/03/01)  MODIFY ディレクトリパスはHybsSystem.url2Dirを通すように変更。
    197//                      queue.setOutputName( new File( ge50vals[i][3] ).getAbsolutePath() , ge50vals[i][4] , ge50vals[i][7] , ge50vals[i][1] ); // 4.3.0.0 (2008/07/18) 要求番号を出力ファイル名に利用
    198//                      queue.setOutputName( HybsSystem.url2dir( ge50vals[i][3] ) , ge50vals[i][4] , ge50vals[i][7] , ge50vals[i][1] ); // 5.10.9.0
    199                        queue.setOutputName( HybsSystem.url2absPath( ge50vals[i][3] ) , ge50vals[i][4] , ge50vals[i][7] , ge50vals[i][1] ); // 5.10.9.2 (2019/03/15)
    200                        queue.setPdfPasswd( ge50vals[i][5] );
    201                        queue.setLang( ge50vals[i][6] );
    202                        queue.setOutputType( ge50vals[i][7] );
    203                        // queue.setThreadId( StringUtil.nval( ge50vals[i][8] , "_DEFALUT_" ) );
    204                        queue.setThreadId( ge50vals[i][0] + "_" + StringUtil.nval( ge50vals[i][8] , "_DEFALUT_" ) ); // 4.3.0.0 (2008/07/15)
    205
    206                        // 5.10.9.0 (2019/03/01)  MODIFY ディレクトリパスはHybsSystem.url2Dirを通すように変更。
    207//                      queue.setTemplateName( new File( ge50vals[i][9] ).getAbsolutePath() + File.separator + ge50vals[i][10] );
    208//                      queue.setTemplateName( HybsSystem.url2dir( ge50vals[i][9] ) + File.separator + ge50vals[i][10]); // 5.10.9.0
    209                        queue.setTemplateName( HybsSystem.url2absPath( ge50vals[i][9] ) + File.separator + ge50vals[i][10]); // 5.10.9.2 (2019/03/15)
    210                        queue.setPrinterName( ge50vals[i][11] );
    211                        queue.setFglocal( "1".equals( ge50vals[i][12] ) );
    212                        queue.setFgcut( "1".equals( ge50vals[i][13] ) );
    213
    214//                      queue.setBsql( ge50vals[i][14] );
    215//                      queue.setHsql( ge50vals[i][15] );
    216//                      queue.setFsql( ge50vals[i][16] );
    217
    218                        queue.setPrtId( ge50vals[i][17] );              // 5.4.3.0
    219                        queue.setPrgDir( ge50vals[i][18] );     // 5.4.3.0
    220                        queue.setPrgFile( ge50vals[i][19] );    // 5.4.3.0
    221
    222                        queue.setGrpId( ge50vals[i][20] );      // 5.9.2.2
    223                        queue.setDmnGrp( ge50vals[i][8] );      // 5.9.2.2
    224                        queue.setFgnoml( ge50vals[i][21] );     // 5.10.0.0 (2018/06/08)
    225
    226                        queue.setManager( this );
    227
    228                        ExecThreadManager.insertQueue( queue );
    229                }
    230        }
    231
    232        /**
    233         * 帳票処理データをキューにセットします。
    234         *
    235         * @og.rev 5.1.2.0 (2010/01/01) HSQL,FSQL,BSQLのセットを廃止します。(このクラス内でデータを直接分割)
    236         *
    237         * @param       queue   ExecQueueオブジェクト
    238         */
    239        public void set( final ExecQueue queue ) {
    240
    241                ResourceManager resource = null;
    242                if( queue.isFglocal() ) {
    243                        resource = ResourceFactory.newInstance( queue.getSystemId(), queue.getLang(), false );
    244                }
    245                else {
    246                        resource = ResourceFactory.newInstance( queue.getLang() );
    247                }
    248//              String[] where = new String[] { queue.getSystemId() , queue.getYkno() } ;
    249
    250                // ヘッダー情報の取得
    251//              DBTableModel header = DBTableModelUtil.makeDBTable( queue.getHsql(), where, resource, appInfo );
    252                DBTableModel header
    253                        = (new DBTableModelCreator( queue.getSystemId(), queue.getListId(), queue.getYkno(), "H", resource )).getTable();
    254                if( header != null && header.getRowCount() > 0 ) {
    255                        queue.setHeader( header );
    256                }
    257
    258                // フッター情報の取得
    259//              DBTableModel footer = DBTableModelUtil.makeDBTable( queue.getFsql(), where, resource, appInfo );
    260                DBTableModel footer
    261                        = (new DBTableModelCreator( queue.getSystemId(), queue.getListId(), queue.getYkno(), "F", resource )).getTable();
    262                if( footer != null && footer.getRowCount() > 0 ) {
    263                        queue.setFooter( footer );
    264                }
    265
    266                // ボディー情報の取得
    267//              DBTableModel body = DBTableModelUtil.makeDBTable( queue.getBsql(), where, resource, appInfo );
    268                DBTableModel body
    269                        = (new DBTableModelCreator( queue.getSystemId(), queue.getListId(), queue.getYkno(), "B", resource )).getTable();
    270                // レイアウトテーブルがないと固定長を分割するSQL文が設定されず、DBTableModelがnullになる
    271                if( body == null ) {
    272                        queue.addMsg( "[ERROR] DBTableModel doesn't exists! maybe Layout-Table(GE52) or Report-Data() is not configured..." + HybsSystem.CR );
    273                        queue.setError();
    274                        throw new RuntimeException();
    275                }
    276                if( body.getRowCount() <= 0 ) {
    277                        queue.addMsg( "[ERROR] Database Body row count is Zero." + queue.getYkno() + HybsSystem.CR );
    278                        queue.setError();
    279                        throw new RuntimeException();
    280                }
    281                if( body.isOverflow() ) {
    282                        queue.addMsg( "[ERROR]Database is Overflow. [" + body.getRowCount() + "]" + HybsSystem.CR );
    283                        queue.addMsg( "[ERROR]Check SystemParameter Data in DB_MAX_ROW_COUNT Overflow" + HybsSystem.CR  );
    284                        queue.setError();
    285                        throw new RuntimeException();
    286                }
    287                queue.setBody( body );
    288        }
    289
    290        /**
    291         * キューを実行中の状態に更新します。
    292         *
    293         * @param       queue   ExecQueueオブジェクト
    294         */
    295        public void execute( final ExecQueue queue ) {
    296                status( queue, STATUS_EXECUTE );
    297        }
    298
    299        /**
    300         * キューを完了済の状態に更新します。
    301         *
    302         * @param       queue   ExecQueueオブジェクト
    303         */
    304        public void complete( final ExecQueue queue ) {
    305                status( queue, STATUS_COMPLETE );
    306        }
    307
    308        /**
    309         * キューをエラーの状態に更新します。
    310         *
    311         * @param       queue   ExecQueueオブジェクト
    312         */
    313        public void error( final ExecQueue queue ) {
    314                status( queue, STATUS_ERROR );
    315                insertErrorMsg( queue );
    316        }
    317
    318        /**
    319         * GE50の状況Cを更新します。
    320         *
    321         * @og.rev 4.2.4.1 (2008/07/09) 更新日時をセット
    322         * @og.rev 5.1.2.0 (2010/01/01) 行数、ページ数も更新する
    323         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
    324         *
    325         * @param       queue   ExecQueueオブジェクト
    326         * @param       status  状況C
    327         */
    328        private void status( final ExecQueue queue, final int status ) {
    329
    330                String dyupd = HybsSystem.getDate( "yyyyMMddHHmmss" ) ;
    331
    332                String[] args
    333                = new String[]{ String.valueOf( status ), queue.getThreadId(), HybsSystem.sys( "HOST_NAME" )
    334                                , String.valueOf( queue.getExecRowCnt() ), String.valueOf( queue.getExecPagesCnt() )
    335                                , dyupd , queue.getSystemId(), queue.getYkno() };
    336
    337//              DBUtil.dbExecute( SQL_UPDATE_GE50, args, appInfo );
    338                DBUtil.dbExecute( SQL_UPDATE_GE50, args, appInfo, DBID );       // 5.5.5.1 (2012/08/07)
    339        }
    340
    341        /**
    342         * GE56にエラーメッセージを出力します。
    343         *
    344         * @og.rev 4.4.0.1 (2009/08/08) エラーメッセージ機能追加
    345         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
    346         * @og.rev 5.10.0.0 (2018/06/08) メール送信条件を追加
    347         *
    348         * @param       queue   ExecQueueオブジェクト
    349         */
    350        private void insertErrorMsg( final ExecQueue queue ) {
    351                String errmsg = queue.getMsg();
    352                if( errmsg.length() > 1300 ) {
    353                        errmsg = errmsg.substring( errmsg.length() - 1300, errmsg.length() );
    354                }
    355
    356                String dyset = HybsSystem.getDate( "yyyyMMddHHmmss" ) ;
    357
    358                String[] args
    359                = new String[]{ queue.getSystemId(), queue.getYkno(), errmsg
    360                                , dyset, dyset, "UNKNOWN", "UNKNOWN", "UNKNOWN" };
    361
    362//              DBUtil.dbExecute( SQL_INSERT_GE56, args, appInfo );
    363                DBUtil.dbExecute( SQL_INSERT_GE56, args, appInfo, DBID );       // 5.5.5.1 (2012/08/07)
    364
    365//              sendMail( queue, errmsg ); // 4.4.0.1 (2009/08/08)
    366                // 5.10.0.0 (2018/06/08) メール送信条件を追加
    367                if(!"1".equals(queue.getFgnoml())){
    368                        sendMail( queue, errmsg ); // 4.4.0.1 (2009/08/08)
    369                }
    370        }
    371
    372        /**
    373         * エラー情報のメール送信を行います。
    374         * エラーメールは、システムパラメータ の COMMON_MAIL_SERVER(メールサーバー)と
    375         * ERROR_MAIL_FROM_USER(エラーメール発信元)と、ERROR_MAIL_TO_USERS(エラーメール受信者)
    376         * がすべて設定されている場合に、送信されます。
    377         *
    378         * @og.rev 4.4.0.1 (2009/08/08) 追加
    379         * @og.rev 5.7.0.4 (2013/11/29) listIdの絞込み
    380         *
    381         * @param       queue           ExecQueueオブジェクト
    382         * @param       inErrMsg        エラーメッセージ
    383         */
    384        private void sendMail( final ExecQueue queue, final String inErrMsg ) {
    385
    386                String   host = HybsSystem.sys( "COMMON_MAIL_SERVER" );
    387                String   from = HybsSystem.sys( "ERROR_MAIL_FROM_USER" );
    388                String[] to = StringUtil.csv2Array( HybsSystem.sys( "ERROR_MAIL_TO_USERS" ) );
    389                String   match_txt = HybsSystem.sys( "REPORT_ERRMAIL_REGEX" ); // 5.7.0.4 (2013/11/29)
    390                if( host != null && from != null && to.length > 0 ) {
    391                        if( match_txt == null || match_txt.length() == 0
    392                                        || queue.getListId() == null || queue.getListId().length() == 0
    393                                        || queue.getListId().matches( match_txt )){     // 5.7.0.4 (2013/11/29)
    394                                // 5.7.0.4 (2013/11/29) listid追加
    395                                String subject = "SYSTEM_ID=[" + queue.getSystemId() + "] , YKNO=[" + queue.getYkno() + "] , "
    396                                                           + "THREAD_ID=[" + queue.getThreadId() + "] , DMN_HOST=[" + HybsSystem.HOST_NAME + "]"
    397                                                           + "LISTID=["+ queue.getListId() + "]";
    398                                try {
    399                                        MailTX tx = new MailTX( host );
    400                                        tx.setFrom( from );
    401                                        tx.setTo( to );
    402                                        tx.setSubject( "帳票エラー：" + subject );
    403                                        tx.setMessage( inErrMsg );
    404                                        tx.sendmail();
    405                                }
    406                                catch( Throwable ex ) {
    407                                        String errMsg = "エラー時メール送信に失敗しました。" + HybsSystem.CR
    408                                                                + " SUBJECT:" + subject                                 + HybsSystem.CR
    409                                                                + " HOST:" + host                                               + HybsSystem.CR
    410                                                                + " FROM:" + from                                               + HybsSystem.CR
    411                                                                + " TO:"   + Arrays.toString( to )              + HybsSystem.CR
    412                                                                + ex.getMessage();              // 5.1.8.0 (2010/07/01) errMsg 修正
    413                                        LogWriter.log( errMsg );
    414                                        LogWriter.log( ex );
    415                                }
    416                        }
    417                }
    418        }
    419
    420        /**
    421         * 帳票明細データを帳票レイアウトテーブルに従って分割し、その結果をDBTableModelとして
    422         * 生成します。
    423         * データの分割は、バイト数ベースで行われるため、エンコードを正しく指定する必要があります。
    424         * エンコード指定は、システムリソースのDB_ENCODEで指定します。
    425         *
    426         * レイアウトテーブルが存在しない場合、又は、帳票データが存在しない場合、DBTableModelは
    427         * nullで返されます。
    428         */
    429        public static class DBTableModelCreator {
    430                // 5.2.0.0 (2010/09/01) Ver4互換モード対応
    431                private static final String CLM = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "COLUMN_NAME" : "CLM";
    432                private static final String TEXT_DATA = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "TEXT" : "TEXT_DATA";
    433
    434                // 5.2.0.0 (2010/09/01) Ver4互換モード対応
    435                // 5.4.4.3 (2012/02/09) FGUSE条件追加対応
    436                private static final String SQL_SELECT_GE52 =
    437//                      " select CLM, START_POS, USE_LENGTH"
    438                        " select "+CLM+", START_POS, USE_LENGTH"
    439                        + " from GE52"
    440                        + " where SYSTEM_ID = ?"
    441                        + " and LISTID = ?"
    442                        + " and KBTEXT = ?"
    443                        + " and FGJ = '1'"
    444                        + " and FGUSE = '1'" // 5.4.4.3
    445                        + " order by SEQ";
    446
    447                // 5.2.0.0 (2010/09/01) Ver4互換モード対応
    448                // 5.10.19.0 (2019/12/27) order by EDBN
    449                private static final String SQL_SELECT_ =
    450//                      " select TEXT_DATA"
    451                        " select "+TEXT_DATA
    452                        + " from "
    453                        + " where SYSTEM_ID = ?"
    454                        + " and YKNO = ?"
    455                        + " and KBTEXT = ?"
    456                        + " and FGJ = '1'"
    457                        + " order by EDNO"; // 5.10.19.0 (2019/12/27)
    458
    459                private static final String ENCODE = HybsSystem.sys( "DB_ENCODE" );
    460
    461                private final String systemId;
    462                private final String listId;
    463                private final String ykno;
    464                private final String kbtext;
    465                private final ResourceManager resource;
    466
    467                private DBTableModel table = null;
    468
    469                /**
    470                 * コンストラクタです。
    471                 *
    472                 * @param sid システムID
    473                 * @param lid 帳票ID
    474                 * @param yk 要求NO
    475                 * @param kt テキスト区分(H:ヘッダー F:フッター B:ボディー)
    476                 * @param res リソースマネージャー
    477                 */
    478                public DBTableModelCreator( final String sid, final String lid, final String yk, final String kt, final ResourceManager res ) {
    479                        systemId = sid;
    480                        listId = lid;
    481                        ykno = yk;
    482                        kbtext = kt;
    483                        resource = res;
    484                        create();
    485                }
    486
    487                /**
    488                 * 帳票データをレイアウト定義に従い分割します。
    489                 *
    490                 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
    491                 * @og.rev 5.9.3.1 (2015/12/18) SJIS-UTF変換時の波ダッシュ問題対応
    492                 */
    493                private void create() {
    494//System.out.println( "debug" );
    495                        String[] ge52Where = new String[] { systemId, listId, kbtext } ;
    496//                      String[][] ge52Vals = DBUtil.dbExecute( SQL_SELECT_GE52, ge52Where, appInfo );
    497                        String[][] ge52Vals = DBUtil.dbExecute( SQL_SELECT_GE52, ge52Where, appInfo, DBID );    // 5.5.5.1 (2012/08/07)
    498//System.out.println( SQL_SELECT_GE52 + " " + Arrays.toString(ge52Where) + "; " + ge52Vals.length );
    499                        if( ge52Vals == null || ge52Vals.length == 0 ) {
    500                                return;
    501                        }
    502
    503                        String[] Where = new String[] { systemId, ykno, kbtext } ;
    504//                      String[][] Vals = DBUtil.dbExecute( SQL_SELECT_, Where, appInfo );
    505                        String[][] Vals = DBUtil.dbExecute( SQL_SELECT_, Where, appInfo, DBID );        // 5.5.5.1 (2012/08/07)
    506//System.out.println( SQL_SELECT_ + " " + Arrays.toString(Where) + "; " + Vals.length );
    507                        if( Vals == null || Vals.length == 0 ) {
    508                                return;
    509                        }
    510
    511                        String[] clms = new String[ge52Vals.length];
    512                        for( int i=0; i<ge52Vals.length; i++ ) {
    513                                clms[i] = ge52Vals[i][0];
    514                        }
    515
    516                        String[][] vals = new String[Vals.length][ge52Vals.length];
    517                        for( int i=0; i<Vals.length; i++ ) {
    518//                              byte[] bytes = StringUtil.makeByte( Vals[i][0], ENCODE );
    519                                byte[] bytes = StringUtil.makeByte( UnicodeCorrecter.correctToCP932( Vals[i][0], ENCODE ), ENCODE ); // 5.9.3.1 (2015/12/18)
    520                                for( int j=0; j<ge52Vals.length; j++ ) {
    521                                        int strpos = Integer.valueOf( ge52Vals[j][1] ) - 1;
    522                                        int len = Integer.valueOf( ge52Vals[j][2] );
    523                                        if( strpos >= bytes.length ) {
    524                                                vals[i][j] = "";
    525                                        }
    526                                        else {
    527                                                if( strpos + len > bytes.length ) {
    528                                                        len = bytes.length - strpos;
    529                                                }
    530                                                vals[i][j] = StringUtil.rTrim( StringUtil.makeString( bytes, strpos, len, ENCODE ) );
    531                                        }
    532                                }
    533                        }
    534                        table = DBTableModelUtil.makeDBTable( clms, vals, resource );
    535                }
    536
    537                /**
    538                 * 分割後のDBTableModelを返します。
    539                 *
    540                 * @return 分割後のDBTableModel
    541                 */
    542                public DBTableModel getTable() {
    543                        return table;
    544                }
    545        }
    546}