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