    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.Arrays;
    019import java.util.List;
    020import java.util.ArrayList;
    021// import java.util.Map;                                                // Collections.unmodifiableMap で使用
    022// import java.util.HashMap;                                    // Collections.unmodifiableMap で使用
    023import java.util.StringJoiner;
    024// import java.util.Collections;
    025import java.util.concurrent.ConcurrentMap;
    026import java.util.concurrent.ConcurrentHashMap;
    027
    028import static org.opengion.fukurou.fileexec.CommandLine.GE70.* ;                // enum を簡素化して使用するための定義
    029
    030/**
    031 * CommandLine は、コマンドリストを管理するクラスです。
    032 *
    033 *<pre>
    034 * コマンドリストは、GE70 テーブルからコマンドを取り出します。
    035 *
    036 * このクラスは、マルチスレッドに対応していません。
    037 *</pre>
    038 * @og.rev 7.0.0.0 (2017/07/07) 新規作成
    039 *
    040 * @version  7.0
    041 * @author   Kazuhiko Hasegawa
    042 * @since    JDK1.8,
    043 */
    044public final class CommandLine {
    045        private static final XLogger LOGGER= XLogger.getLogger( CommandLine.class.getSimpleName() );            // ログ出力
    046
    047        /** GE70 テーブルのカラム定義の enum */
    048        public enum GE70 {
    049//      public static enum GE70 {
    050                /** GE70 テーブルから検索するカラム名 */
    051                /** GE70 カラム */ SYSTEM_ID,
    052                /** GE70 カラム */ RSRV_NO,
    053                /** GE70 カラム */ NAME_JA,
    054                /** GE70 カラム */ EXECID,
    055                /** GE70 カラム */ FGYKAN,
    056                /** GE70 カラム */ DIR_BASE,
    057                /** GE70 カラム */ DIR_SUB,
    058                /** GE70 カラム */ DIR_WORK,
    059                /** GE70 カラム */ DIR_BKUP_OK,
    060                /** GE70 カラム */ DIR_BKUP_NG,
    061                /** GE70 カラム */ FILE_FILTER ;
    062
    063                /** 取込予約ﾌﾗｸﾞ 1:実行 のみ処理。ORDER_BY も入れておきます。 */
    064                // 取込予約ﾌﾗｸﾞ 1:実行 2:停止
    065                private static final String FROM_WHERE = " from GE70 where FGJ='1' and FGYKAN='1' order by SYSTEM_ID,RSRV_NO" ;
    066
    067//              /** order by で、SYSTEM_ID,RSRV_NO順に処理されるようにしておきます。 */
    068//              // 取込予約ﾌﾗｸﾞ 1:実行 2:停止
    069//              private static final String ORDER_BY = " order by SYSTEM_ID,RSRV_NO" ;
    070
    071//              private static final String FGYKAN1 = "('1','3','4')" ; // 起動直後
    072//              private static final String FGYKAN2 = "('1','4')" ;             // ループ処理
    073
    074                /** 列挙子のCSV形式文字列 のキャッシュ */
    075                public static final String SELECT  ;            // GE70検索
    076//              public static final String SELECT1 ;            // 起動直後
    077//              public static final String SELECT2 ;            // ループ処理
    078                static {
    079                        final StringJoiner sj = new StringJoiner( "," , "select " , FROM_WHERE );
    080                        Arrays.stream( values() ).forEachOrdered( v -> sj.add( v.name() ) );
    081                        SELECT  = sj.toString() ;
    082//                      SELECT1 = sj.toString() + FGYKAN1 + ORDER_BY ;
    083//                      SELECT2 = sj.toString() + FGYKAN2 + ORDER_BY ;
    084                }
    085
    086                /** 列挙子の序数(カラムの並び順) */
    087                public final int NO ;
    088
    089                /** private コンストラクター */
    090                GE70() { NO = ordinal(); }
    091//              private GE70() { NO = ordinal(); }
    092        };
    093
    094//      // 予約ﾌﾗｸﾞ は、値に応じて、セットする値が異なる。
    095//      /** Collections.unmodifiableMap を使用。 */
    096//      @SuppressWarnings( "serial" )
    097//      private static final Map<String,String> IN2OUT = Collections.unmodifiableMap(
    098//              new HashMap<String, String>() {{
    099//                      put( "1" , "3" );               // 1:登録 → 3:実行中
    100//                      put( "4" , "2" );               // 4:停止 → 2:済
    101//      }});
    102
    103//      // 予約ﾌﾗｸﾞ は、値に応じて、セットする値が異なる。
    104//      // static イニシャライザで行う場合、ｴﾝｼﾞﾝのｿｰｽﾁｪｯｸで、警告5 が出るため、一時保留
    105//      private static final Map<String,String> IN2OUT;
    106//      static {
    107//              final Map<String,String> in2out = new HashMap<>();
    108//              in2out.put( "1" , "3" );                // 1:登録 → 3:実行中
    109//              in2out.put( "4" , "2" );                // 4:停止 → 2:済
    110//              IN2OUT = Collections.unmodifiableMap( in2out );
    111//      }
    112
    113//      // GE70 で、IN2OUT に対応した予約ﾌﾗｸﾞ を更新します。
    114//      private static final String[] UPD_KEYS  = new String[] { "FGYKAN","DYUPD","PGUPD" };
    115//      private static final String   UPD_WHERE = "SYSTEM_ID=? and RSRV_NO=? and FGJ='1'";
    116//
    117//      private static final String UPD_QUER = DBUtil.getUpdateSQL( "GE70",UPD_KEYS,null,null,UPD_WHERE );
    118
    119//      // 7.2.5.3 (2020/06/16) 処理のスレッドを停止した時に、GF70.FGYKANを、3:実行中→1: 待機中  に更新する。
    120//      private static final String STOP_FGYKAN = "update GE70 set FGYKAN='1',DYUPD=?,PGUPD=? where FGYKAN='3'";
    121
    122        private final String[]          cmndData        ;
    123        private final String            cmndStr         ;                       // toString() 時に使用する、cmndList の文字列表現
    124
    125        private final ConcurrentMap<String,String> kvMap = new ConcurrentHashMap<>();   // パラメータ(key1=val1 key2=val2 ･･･ のリスト)のMap
    126
    127        /**
    128         * データを引数にとるコンストラクタ
    129         *
    130         * SYSTEM_ID,RSRV_NO,NAME_JA,EXECID,FGYKAN,DIR_BASE,DIR_SUB,DIR_WORK,DIR_BKUP_OK,DIR_BKUP_NG,FILE_FILTER
    131         * ｼｽﾃﾑID,予約番号,名称,処理ID,取込予約ﾌﾗｸﾞ,取込ﾍﾞｰｽﾌｫﾙﾀﾞ,取込ｻﾌﾞﾌｫﾙﾀﾞ,処理ﾌｫﾙﾀﾞ(WORK),処理済ﾌｫﾙﾀﾞ(正常),処理済ﾌｫﾙﾀﾞ(異常),検索条件 を
    132         * 文字列として順番に持っています。
    133         *
    134         * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加
    135         *
    136         * @param       values  データ
    137         * @throws      RuntimeException 引数に不整合があった場合。
    138         */
    139        private CommandLine( final String[] values ) {
    140                cmndData = Arrays.copyOf( values, values.length );
    141
    142                cmndStr = Arrays.toString( cmndData );
    143                LOGGER.debug( () -> "① values=" + cmndStr );
    144
    145                if( cmndData[RSRV_NO.NO] == null || cmndData[EXECID.NO] == null ) {
    146                        // MSG3001 = ｺﾏﾝﾄﾞﾘｽﾄに、予約番号,取込ID,処理IDは必須です。[{0}]
    147                        throw MsgUtil.throwException( "MSG3001" , cmndStr );
    148                }
    149
    150                // key=val のパラメータ文字列を、Map化します。
    151                final String filter = cmndData[FILE_FILTER.NO];                                         // 検索条件となるフィルター情報
    152                if( filter != null && !filter.trim().isEmpty() && filter.indexOf( '=' ) >= 0 ) {
    153                        // 6番目のparamsは、key=valの羅列
    154                        for( final String kvStr : filter.split( " " ) ) {                               // スペースで分割
    155                                final int ad = kvStr.indexOf( '=' );                                            // key=val を見つける。
    156                                if( ad > 0 ) {
    157                                        final String key = kvStr.substring( 0,ad ).trim();
    158                                        final String val = kvStr.substring( ad+1 ).trim();
    159                                        if( !key.isEmpty() ) { kvMap.put( key , val ); }                // keyが空文字の場合は、無視
    160                                }
    161                        }
    162                }
    163        }
    164
    165        /**
    166         * 設定値を返します。
    167         *
    168         * @param       clm GE70ﾃｰﾌﾞﾙを定義したenum
    169         * @return      設定値
    170         */
    171        public String getValue( final GE70 clm ) { return cmndData[ clm.NO ]; }
    172
    173        /**
    174         * パラメータ(key1=val1 key2=val2 ･･･ のリスト)のMapを返します。
    175         *
    176         * @return      パラメータ(key1=val1 key2=val2 ･･･ のリスト)のMap
    177         * @og.rtnNotNull
    178         */
    179        public ConcurrentMap<String,String> getKeyValMap() { return kvMap ; }
    180
    181        /**
    182         * 指定のGE70テーブルを読み込んで、CommandLineオブジェクトのListを作成します。
    183         *
    184//       * @param       isFirst 起動直後の初期処理かどうかの判定ﾌﾗｸﾞ(起動直後は、true)
    185         * @return      CommandLineオブジェクトのList
    186         */
    187//      public static List<CommandLine> dbCommand( final boolean isFirst) {
    188        public static List<CommandLine> dbCommand() {
    189                final List<CommandLine> cmndList = new ArrayList<>();
    190
    191//              // 更新用の値
    192//              final List<String[]> upddbData = new ArrayList<>();
    193//              final String NOW  = StringUtil.getTimeFormat();
    194//              final String PGID = "CMNDLine";
    195
    196//              final List<String[]> cmdRow = DBUtil.dbQuery( isFirst ? SELECT1 : SELECT2 );    // GE70.SELECT
    197                final List<String[]> cmdRow = DBUtil.dbQuery( SELECT );                                                 // GE70.SELECT
    198                for( final String[] cmdClms : cmdRow ) {
    199                        cmndList.add( new CommandLine( cmdClms ) );
    200
    201//                      final String fgKan = IN2OUT.get( cmdClms[FGYKAN.NO] );                  // 予約ﾌﾗｸﾞ
    202//                      if( fgKan != null ) {                           // 予約ﾌﾗｸﾞ が、対象の場合。
    203//                              // 予約ﾌﾗｸﾞを、IN2OUT で変換した値に更新します。
    204//                              // M_FileExec テーブルの更新カラム
    205//                              final String[] updVals = new String[] {
    206//                                        fgKan                                         // 予約ﾌﾗｸﾞ                       FGYKAN
    207//                                      , NOW                                           // 更新日時                 DYUPD
    208//                                      , PGID                                          // 更新PG                 PGUPD
    209//                                      , cmdClms[SYSTEM_ID.NO]         // ｼｽﾃﾑID                       SYSTEM_ID
    210//                                      , cmdClms[RSRV_NO.NO]           // 予約番号                 RSRV_NO
    211//                              } ;
    212//                              upddbData.add( updVals );
    213//                      }
    214                }
    215
    216//              if( ! upddbData.isEmpty() ) {
    217//                      DBUtil.execute( UPD_QUER , upddbData );
    218//              }
    219
    220                return cmndList ;
    221        }
    222
    223//      /**
    224//       * 終了時に、クリアするために GE70テーブルを更新する。
    225//       *
    226//       * 予約ﾌﾗｸﾞ(FGYKAN)を、3:実行中 から 1: 待機中 に変更する。
    227//       *
    228//       * @og.rev 7.2.5.3 (2020/06/16) 処理のスレッドを停止した時に、GF70.FGYKANを、3:実行中→1: 待機中 に更新する。
    229//       */
    230//      public static void stopFgykan() {
    231//              // 更新用の値
    232//              final String NOW  = StringUtil.getTimeFormat();
    233//              final String PGID = "CMNDLine";
    234//
    235//              DBUtil.execute( STOP_FGYKAN,NOW,PGID ); // 3:実行中→1: 待機中 に更新
    236//      }
    237
    238        /**
    239         *コマンドリストクラスの文字列表現を返します。
    240         *
    241         * @return      コマンドリストクラスの文字列表現
    242         */
    243        @Override
    244        public String toString() { return cmndStr ; }
    245}