    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.util.concurrent.ConcurrentMap;
    019import java.util.concurrent.ConcurrentHashMap;
    020import java.util.StringJoiner;
    021import java.util.Arrays;
    022import java.util.List;
    023import java.nio.file.Path;
    024
    025import org.opengion.fukurou.util.StringUtil;
    026
    027/**
    028 * AppliExec は、アプリケーションの実行を行う共通の処理クラスです。
    029 *
    030 *<pre>
    031 *
    032 * ここでは、GE72の処理IDに応じた方法で実行します。
    033 *
    034 *</pre>
    035 *
    036 * @og.rev 7.0.0.0 (2017/07/07) 新規作成
    037 *
    038 * @version  7.0
    039 * @author   Kazuhiko Hasegawa
    040 * @since    JDK1.8,
    041 */
    042public final class AppliExec {
    043        private static final XLogger LOGGER= XLogger.getLogger( AppliExec.class.getSimpleName() );              // ログ出力
    044
    045        /** GE72 テーブルのカラム定義の enum */
    046        public enum GE72 {
    047//      public static enum GE72 {
    048                /** GE72 テーブルから検索するカラム名 */
    049//              RUNTYPE,RUNPG,CLMS,PARAMS,DBID,TABLE_NAME,SHT_NOS,FILE_ENC,SKIP_CNT ;
    050                /** GE72 カラム */ EXECID,
    051                /** GE72 カラム */ RUNTYPE,
    052                /** GE72 カラム */ RUNPG,
    053                /** GE72 カラム */ CLMS,
    054                /** GE72 カラム */ PARAMS,
    055                /** GE72 カラム */ DBID,
    056                /** GE72 カラム */ TABLE_NAME,
    057                /** GE72 カラム */ SHT_NOS,
    058                /** GE72 カラム */ FILE_ENC,
    059                /** GE72 カラム */ SKIP_CNT ;                      // 7.2.1.0 (2020/03/13) EXECID 追加
    060
    061                /** order by で、開始日時(ST_TIME)順に処理されるようにしておきます。 */
    062                private static final String FROM_WHERE = " from GE72 where SYSTEM_ID=? and EXECID=? and FGJ='1'" ;              // １件のみのはず
    063
    064                /** 列挙子のCSV形式文字列 のキャッシュ  */
    065                public static final String SELECT ;
    066                static {
    067                        final StringJoiner sj = new StringJoiner( "," , "select " , FROM_WHERE );
    068                        Arrays.stream( values() ).forEachOrdered( v -> sj.add( v.name() ) );
    069                        SELECT = sj.toString();
    070                }
    071
    072                /** 列挙子の序数(カラムの並び順) */
    073                public final int NO ;
    074
    075                /** private コンストラクター */
    076                GE72() { NO = ordinal(); }
    077//              private GE72() { NO = ordinal(); }
    078        };
    079
    080        // GE72()のﾕﾆｰｸｷｰは、systemId + execId だが、GE70()のﾕﾆｰｸｷｰは、systemId + rsrv_no
    081        private static final ConcurrentMap<String,AppliExec> APP_EXEC_MAP = new ConcurrentHashMap<>();
    082
    083        private final String[] ge72Data ;
    084
    085        private final RunExec runexec ;                 // これもキャッシュできますが、とりあえず動くまでは毎回作成します。
    086
    087        /**
    088         * private コンストラクタ
    089         *
    090         * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加
    091         *
    092         * @param       systemId        システムID
    093         * @param       execId          処理ID
    094         */
    095        private AppliExec( final String systemId , final String execId ) {
    096                LOGGER.debug( () -> "⑥ systemId=" + systemId + " , execId=" + execId );
    097
    098                final List<String[]> cmdRow = DBUtil.dbQuery( GE72.SELECT , systemId , execId );
    099
    100                if( cmdRow.isEmpty() ) {
    101                        // MSG3001 = コマンドリストに、予約番号,取込ID,処理IDは必須です。[{0}]
    102                        throw MsgUtil.throwException( "MSG3001" , "SYSTEM_ID=" + systemId + " , EXECID=" + execId );
    103                }
    104
    105                ge72Data = cmdRow.get(0);               // １件のみのはず
    106                final String type = ge72Data[GE72.RUNTYPE.NO];
    107
    108                final String key ;
    109                switch( type ) {
    110                        case "0" : key = "NONE";        break;                  // なにもしない
    111                        case "1" : key = "DBIN";        break;                  // DB入力
    112        //              case "2" : key = "PLSQL";       break;                  // PL/SQLコール
    113                        case "3" : key = "BAT";         break;                  // BATファイルコール
    114        //              case "4" : key = "JSP";         break;                  // JSPファイルコール（URLコネクション）
    115                        default  : key = null;          break;                  // なにもしない(runTypeなしエラー)
    116                }
    117
    118                if( key == null ) {
    119                        // MSG3002 = RUNTYPEに対応するRunExec実装クラスがありません。[{0}]
    120                        throw MsgUtil.throwException( "MSG3002" , "RUNTYPE=" + type + " , systemId=" + systemId + " , execId=" + execId );
    121                }
    122
    123                runexec = (RunExec)StringUtil.newInstance( "org.opengion.fukurou.fileexec.RunExec_" + key );
    124        }
    125
    126        /**
    127         * システムIDと処理IDから、対応するAppliExecオブジェクトを返します。
    128         *
    129         * AppliExecオブジェクトを、動的に作成し、システムID + 予約番号 をキーにキャッシュします。
    130         *
    131         * 何らかの Exception が、throw された場合は、null を返します。
    132         *
    133         * @og.rev 7.2.1.0 (2020/03/13) APP_EXEC_MAPのキーを、systemId + rsrv_no に変更します。
    134         *
    135         * @param       systemId        システムID
    136         * @param       rsrvNo          予約番号(文字列のまま扱います)
    137         * @param       execId          処理ID
    138         * @return      AppliDataオブジェクト（作成できなければ、null）
    139         */
    140//      public static AppliExec newInstance( final String systemId , final String execId ) {
    141        public static AppliExec newInstance( final String systemId , final String rsrvNo , final String execId ) {
    142//              final String mapKey = systemId + "_" + execId ;
    143                final String mapKey = systemId + "_" + rsrvNo ;
    144
    145                return APP_EXEC_MAP.computeIfAbsent( mapKey , key -> new AppliExec( systemId,execId ) );
    146        }
    147
    148        /**
    149         * システムID + 予約番号 をキーにキャッシュからAppliExecオブジェクトを削除します。
    150         *
    151         * 新しい AppliExecオブジェクトを作成する際に、GE72 を再読み込みします。
    152         * 何か定義変更を行った後、読み取りスレッドを停止すると同時に、キャッシュを削除すれば、
    153         * 次回起動時には、DBの設定を再読み込みします。
    154         *
    155         * @og.rev 7.2.1.0 (2020/03/13) APP_EXEC_MAPのキーを、systemId + rsrv_no に変更します。
    156         *
    157         * @param       systemId        システムID
    158         * @param       rsrvNo          予約番号(文字列のまま扱います)
    159         */
    160        public static void removeInstance( final String systemId , final String rsrvNo ) {
    161                final String mapKey = systemId + "_" + rsrvNo ;
    162
    163                APP_EXEC_MAP.remove( mapKey );
    164        }
    165
    166        /**
    167         * GE72.RUNTYPE に基づいて、各種処理を実行します。
    168         *
    169         * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加
    170         *
    171         * @param       path 処理するファイルパス
    172         * @return      処理件数(正は成功、マイナスは異常時の行番号)
    173         */
    174        public int exec( final Path path ) {
    175                return runexec.exec( path,ge72Data ) ;
    176        }
    177
    178        /**
    179         * GE72.RUNTYPE に基づいて、各種処理を実行します。
    180         *
    181         * @og.rev 7.2.1.0 (2020/03/13) 新規追加
    182         *
    183         * @param       path 処理するファイルパス
    184         * @param       fgtkan 取込完了ﾌﾗｸﾞ(0:取込なし , 1:処理中 , 2:済 , 7:ﾃﾞｰﾓﾝｴﾗｰ , 8:ｱﾌﾟﾘｴﾗｰ)
    185         * @param       errMsg ｴﾗｰﾒｯｾｰｼﾞ
    186         */
    187        public void endExec( final Path path , final String fgtkan , final String errMsg ) {
    188                runexec.endExec( path,ge72Data,fgtkan,errMsg ) ;
    189        }
    190}