    001/*
    002 * Copyright (c) 2017 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.fukurou.fileexec;
    017
    018import java.nio.file.Files;
    019import java.nio.file.Path;
    020import java.util.Arrays;
    021
    022import static org.opengion.fukurou.fileexec.CommandLine.GE70;           // enum を簡素化して使用するための定義
    023
    024/**
    025 * FileExec は、処理の中心で、デーモン一つに対応する処理開始クラスです。
    026 *
    027 *<pre>
    028 * このクラスは、ファイルスキャンのフォルダ単位に、起動され、ファイルのイベントを処理します。
    029 *</pre>
    030 *
    031 * @og.rev 7.0.0.0 (2017/07/07) 新規作成
    032 *
    033 * @version  7.0
    034 * @author   Kazuhiko Hasegawa
    035 * @since    JDK1.8,
    036 */
    037public class FileExec {
    038        private static final XLogger LOGGER= XLogger.getLogger( FileExec.class.getName() );             // ログ出力
    039
    040        /** システム依存の改行記号(String)。        */
    041        public static final String CR = System.getProperty("line.separator");
    042
    043        private final TBL_GE71  tableGE71 ;             // 6.9.7.0 (2018/05/14) PMD
    044
    045        private final String    systemId ;              // ｼｽﾃﾑID
    046        private final String    rsrvNo;                 // 予約番号
    047        private final String    execId;                 // 処理ID
    048
    049        private final String    fileFltr ;              // 検索条件
    050
    051        private final BasePath  basePath ;              // 各種パスを管理しているｸﾗｽ
    052
    053        private final FileWatch fWatch ;                // 取込ﾌｫﾙﾀﾞをイベントで監視する
    054
    055        /**
    056         * コマンドラインを引数に取るコンストラクター
    057         *
    058         * ファイルの監視を開始します。
    059         *
    060         * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加
    061         *
    062         * @param       cmndLine        コマンドラインオブジェクト
    063         */
    064        public FileExec( final CommandLine cmndLine ) {
    065                LOGGER.debug( () -> "② CommandLine=" + cmndLine );
    066
    067                systemId        = cmndLine.getValue( GE70.SYSTEM_ID );          // ｼｽﾃﾑID
    068                rsrvNo          = cmndLine.getValue( GE70.RSRV_NO );            // 予約番号
    069                execId          = cmndLine.getValue( GE70.EXECID );                     // 処理ID
    070                fileFltr        = cmndLine.getValue( GE70.FILE_FILTER );        // 検索条件
    071
    072                basePath = new BasePath(
    073                                        cmndLine.getValue( GE70.DIR_BASE )              ,       // 取込ﾍﾞｰｽﾌｫﾙﾀﾞ
    074                                        cmndLine.getValue( GE70.DIR_SUB  )              ,       // 取込ｻﾌﾞﾌｫﾙﾀﾞ
    075                                        cmndLine.getValue( GE70.DIR_WORK    )   ,       // 処理ﾌｫﾙﾀﾞ(WORK)
    076                                        cmndLine.getValue( GE70.DIR_BKUP_OK )   ,       // 処理済ﾌｫﾙﾀﾞ(正常)
    077                                        cmndLine.getValue( GE70.DIR_BKUP_NG ) );        // 処理済ﾌｫﾙﾀﾞ(異常)
    078
    079                tableGE71 = new TBL_GE71( systemId,rsrvNo,execId );             // 6.9.7.0 (2018/05/14) PMD
    080
    081                fWatch  = new FileWatch( basePath.SUB_PATH );                   // ｻﾌﾞﾌｫﾙﾀﾞをイベントで監視する
    082        }
    083
    084        /**
    085         * このコマンドに対応するフォルダの監視を開始します。
    086         *
    087         * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加
    088         */
    089        public void watchStart() {
    090                LOGGER.debug( () -> "④ [watchStart()]" );
    091
    092                fWatch.setEventKinds( FileWatch.CREATE , FileWatch.MODIFY );
    093                fWatch.setPathMatcher( new PathMatcherSet().addFileName( fileFltr ) );          // ファイルの検索条件
    094                fWatch.callback( (event,fPath) -> checkFile( event,fPath ) );
    095                fWatch.start();
    096        }
    097
    098        /**
    099         * このコマンドに対応するフォルダの監視を終了します。
    100         *
    101         * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加
    102         */
    103        public void watchStop() {
    104                LOGGER.debug( () -> "③ [watchStop()]" );
    105
    106                fWatch.stop();
    107        }
    108
    109        /**
    110         * 更新されたファイルをチェックします。
    111         *
    112         * ※ バックアップ処理してから、DB取り込み処理を行います。
    113         * よって、DB登録処理中にエラーが発生した場合でも、バックアップ済みです
    114         *
    115         * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加
    116         *
    117         * @param       event     発生イベントの名称
    118         * @param       filePath ファイルパス(相対パス)
    119         */
    120        private void checkFile( final String event,final Path filePath ) {
    121                Path bkup   = null;
    122                Path okFile = null;
    123                Path ngFile = null;
    124                String errMsg = "";
    125
    126                try {
    127                        // FileUtil.stablePath は、書き込まれている途中かもしれないので、安定するまで待つ。
    128                        if( FileUtil.stablePath( filePath ) ) {
    129                                LOGGER.debug( () -> "⑤ event=" + event + " , Path=" + filePath );
    130
    131                                // ワークへ移動してから、DB取り込み処理を行います。
    132                                bkup = FileUtil.backup( filePath,basePath.WORK_PATH );                                                  // WORKに移動します。
    133
    134                                final String  tmStr = StringUtil.getTimeFormat();                                                               // 開始時刻
    135
    136                                final AppliExec appli = AppliExec.newInstance( systemId,execId );
    137
    138                                final int suKekka = appli.exec( bkup );
    139
    140                                final String fgtKan ;                                                                                   // 取込完了ﾌﾗｸﾞ 1:処理中 2:済 7:ﾃﾞｰﾓﾝｴﾗｰ 8:ｱﾌﾟﾘｴﾗｰ
    141                                if( suKekka >= 0 ) {
    142                                        okFile = FileUtil.backup( bkup,basePath.OK_PATH );                      // 処理済OKﾌｫﾙﾀﾞに移動
    143                                        fgtKan = "2" ;
    144                                }
    145                                else {
    146                                        ngFile = FileUtil.backup( bkup,basePath.NG_PATH );                      // 処理済NGﾌｫﾙﾀﾞに移動
    147                                        fgtKan = "8" ;
    148                                }
    149
    150                                tableGE71.dbInsert( fgtKan , tmStr , filePath , okFile , ngFile , suKekka , errMsg );
    151
    152                                LOGGER.info( () -> "DAT execute. " + filePath + " , FGTKAN=" + fgtKan + " , kensu=" + suKekka );
    153                        }
    154                        else {
    155                                // エラーにせず、保留にします。
    156                                LOGGER.info( () -> "checkFile Not stablePath. " + filePath );
    157                        }
    158                }
    159                catch( final Throwable th ) {
    160                        // MSG0021 = 予期せぬエラーが発生しました。\n\tﾒｯｾｰｼﾞ=[{0}]
    161                        errMsg = MsgUtil.errPrintln( th , "MSG0021" , filePath );
    162
    163                        // 6.9.8.0 (2018/05/28) FindBugs: メソッド呼び出しは非 null パラメータに対して null を渡している
    164//                      if( Files.exists( bkup ) ) {                                                            // WORKに移動するところまでは、成功しており、その後の、移動ができていない。
    165                        if( bkup != null && Files.exists( bkup ) ) {                            // WORKに移動するところまでは、成功しており、その後の、移動ができていない。
    166                                ngFile = FileUtil.backup( bkup,basePath.NG_PATH );              // 処理済NGﾌｫﾙﾀﾞに移動
    167                        }
    168
    169                        tableGE71.dbInsert( "7" , StringUtil.getTimeFormat() , filePath , null , ngFile , -1 , errMsg );                // -1 は、エラーを示します。
    170                }
    171        }
    172
    173        /**
    174         *このクラスの文字列表現を返します。
    175         *
    176         * @return      クラスの文字列表現
    177         */
    178        @Override
    179        public String toString() {
    180//              return systemId + " , " + execId ;
    181                return String.join( " , " , systemId , rsrvNo , execId );               // 6.9.7.0 (2018/05/14) PMD
    182        }
    183
    184        /**
    185         * GE71 実行結果をデータベースに書き込む内部クラスです。 ( 6.9.7.0 (2018/05/14) PMD )
    186         */
    187        private static final class TBL_GE71 {
    188                private static final String[] KEYS              = new String[] {  "SYSTEM_ID","RSRV_NO","EXECID","FGTKAN","TMSTR","TMEND"
    189                                                                                                                                , "FILE_IN","FILE_OK","FILE_NG","SUTORI ","ERRMSG "
    190                                                                                                                                , "DYSET","DYUPD" };
    191                private static final String[] CON_KEYS  = new String[] { "FGJ","PGSET"  ,"PGUPD"  };
    192                private static final String[] CON_VALS  = new String[] { "1"  ,"FileExec","FileExec" };
    193
    194                private static final String INS_QUERY = DBUtil.getInsertSQL( "GE71",KEYS,CON_KEYS,CON_VALS );
    195
    196                private final String systemId ;                 // システムID
    197                private final String rsrvNo;                    // 予約番号
    198                private final String execId ;                   // 処理ID
    199
    200                /**
    201                 * GE71 データベースにインサート処理を行うクラスのコンストラクター
    202                 *
    203                 * @param       sysId   システムID
    204                 * @param       rsNo    予約番号
    205                 * @param       exId    処理ID
    206                 */
    207                public TBL_GE71( final String sysId , final String rsNo ,final String exId ) {
    208                        systemId = sysId ;
    209                        rsrvNo   = rsNo ;
    210                        execId   = exId;
    211                }
    212
    213                /**
    214                 * データベースにインサート処理を行います。
    215                 *
    216                 * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加
    217                 *
    218                 * @param       fgtKan  取込完了ﾌﾗｸﾞ
    219                 * @param       tmStr   開始時刻
    220                 * @param       fIn             取込ﾌｧｲﾙパス
    221                 * @param       fOk             処理済OKﾌｧｲﾙパス
    222                 * @param       fNg             処理済NGﾌｧｲﾙパス
    223                 * @param       sutori  取込数
    224                 * @param       errMsg  ｴﾗｰﾒｯｾｰｼﾞ
    225                 */
    226                public void dbInsert( final String fgtKan , final String tmStr , final Path fIn , final Path fOk , final Path fNg , final int sutori , final String errMsg ) {
    227                        final String NOW = StringUtil.getTimeFormat();
    228
    229                        final String fileIn = fIn == null ? "" : fIn.toString() ;
    230                        final String fileOk = fOk == null ? "" : fOk.toString() ;
    231                        final String fileNg = fNg == null ? "" : fNg.toString() ;
    232
    233                        // GE71 テーブルのカラム
    234                        final String[] values = new String[] {
    235                                  systemId                                      // ｼｽﾃﾑID               SYSTEM_ID
    236                                , rsrvNo                                        // 予約番号         RSRV_NO
    237                                , execId                                        // 処理ID         EXECID
    238                                , fgtKan                                        // 取込完了ﾌﾗｸﾞ     FGTKAN
    239                                , tmStr                                         // 開始時刻         TMSTR
    240                                , NOW                                           // 完了時刻         TMEND
    241                                , fileIn                                        // 取込ﾌｧｲﾙ               FILE_IN
    242                                , fileOk                                        // 処理済OKﾌｧｲﾙ    FILE_OK
    243                                , fileNg                                        // 処理済NGﾌｧｲﾙ    FILE_NG
    244                                , String.valueOf( sutori )      // 取込件数         SUTORI
    245                                , errMsg                                        // ｴﾗｰﾒｯｾｰｼﾞ    ERRMSG
    246                                , NOW                                           // 登録日時         DYSET
    247                                , NOW                                           // 更新日時         DYUPD
    248                        } ;
    249
    250                        LOGGER.debug( () -> "⑥ GE71.dbInsert query=" + INS_QUERY + "\n\t values=" + Arrays.toString( values ) );
    251
    252                        DBUtil.execute( INS_QUERY , values );
    253                }
    254        }
    255}