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
028// import static org.opengion.fukurou.fileexec.CommandLine.GE70.* ;             // enum を簡素化して使用するための定義 // 8.5.4.2 (2024/01/12) 個別に記述
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        }               // 8.5.4.2 (2024/01/12) PMD 7.0.0 UnnecessarySemicolon
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                if( cmndData[GE70.RSRV_NO.NO] == null || cmndData[GE70.EXECID.NO] == null ) {   // 8.5.4.2 (2024/01/12)
147                        // MSG3001 = コマンドリストに、予約番号,取込ID,処理IDは必須です。[{0}]
148                        throw MsgUtil.throwException( "MSG3001" , cmndStr );
149                }
150
151                // key=val のパラメータ文字列を、Map化します。
152//              final String filter = cmndData[FILE_FILTER.NO];                                         // 検索条件となるフィルター情報
153                final String filter = cmndData[GE70.FILE_FILTER.NO];                            // 8.5.4.2 (2024/01/12) 検索条件となるフィルター情報
154                // 8.5.4.2 (2024/01/12) PMD 7.0.0 InefficientEmptyStringCheck 対応
155//              if( filter != null && !filter.trim().isEmpty() && filter.indexOf( '=' ) >= 0 ) {
156                // fukurou.util.StringUtil#isNull(String) を使いたくなかった。
157                if( filter != null && !filter.isBlank() && filter.indexOf( '=' ) >= 0 ) {
158                        // 6番目のparamsは、key=valの羅列
159                        for( final String kvStr : filter.split( " " ) ) {                               // スペースで分割
160                                final int ad = kvStr.indexOf( '=' );                                            // key=val を見つける。
161                                if( ad > 0 ) {
162                                        final String key = kvStr.substring( 0,ad ).trim();
163                                        final String val = kvStr.substring( ad+1 ).trim();
164                                        if( !key.isEmpty() ) { kvMap.put( key , val ); }                // keyが空文字の場合は、無視
165                                }
166                        }
167                }
168        }
169
170        /**
171         * 設定値を返します。
172         *
173         * @param       clm GE70テーブルを定義したenum
174         * @return      設定値
175         */
176        public String getValue( final GE70 clm ) { return cmndData[ clm.NO ]; }
177
178        /**
179         * パラメータ(key1=val1 key2=val2 ・・・ のリスト)のMapを返します。
180         *
181         * @return      パラメータ(key1=val1 key2=val2 ・・・ のリスト)のMap
182         * @og.rtnNotNull
183         */
184        public ConcurrentMap<String,String> getKeyValMap() { return kvMap ; }
185
186        /**
187         * 指定のGE70テーブルを読み込んで、CommandLineオブジェクトのListを作成します。
188         *
189//       * @param       isFirst 起動直後の初期処理かどうかの判定フラグ(起動直後は、true)
190         * @return      CommandLineオブジェクトのList
191         */
192//      public static List<CommandLine> dbCommand( final boolean isFirst) {
193        public static List<CommandLine> dbCommand() {
194                final List<CommandLine> cmndList = new ArrayList<>();
195
196//              // 更新用の値
197//              final List<String[]> upddbData = new ArrayList<>();
198//              final String NOW  = StringUtil.getTimeFormat();
199//              final String PGID = "CMNDLine";
200
201//              final List<String[]> cmdRow = DBUtil.dbQuery( isFirst ? SELECT1 : SELECT2 );    // GE70.SELECT
202//              final List<String[]> cmdRow = DBUtil.dbQuery( SELECT );                                                 // GE70.SELECT
203                final List<String[]> cmdRow = DBUtil.dbQuery( GE70.SELECT );                                    // 8.5.4.2 (2024/01/12) GE70.SELECT
204                for( final String[] cmdClms : cmdRow ) {
205                        cmndList.add( new CommandLine( cmdClms ) );
206
207//                      final String fgKan = IN2OUT.get( cmdClms[FGYKAN.NO] );                  // 予約フラグ
208//                      if( fgKan != null ) {                           // 予約フラグ が、対象の場合。
209//                              // 予約フラグを、IN2OUT で変換した値に更新します。
210//                              // M_FileExec テーブルの更新カラム
211//                              final String[] updVals = new String[] {
212//                                        fgKan                                         // 予約フラグ                       FGYKAN
213//                                      , NOW                                           // 更新日時                 DYUPD
214//                                      , PGID                                          // 更新PG                 PGUPD
215//                                      , cmdClms[SYSTEM_ID.NO]         // システムID                       SYSTEM_ID
216//                                      , cmdClms[RSRV_NO.NO]           // 予約番号                 RSRV_NO
217//                              } ;
218//                              upddbData.add( updVals );
219//                      }
220                }
221
222//              if( ! upddbData.isEmpty() ) {
223//                      DBUtil.execute( UPD_QUER , upddbData );
224//              }
225
226                return cmndList ;
227        }
228
229//      /**
230//       * 終了時に、クリアするために GE70テーブルを更新する。
231//       *
232//       * 予約フラグ(FGYKAN)を、3:実行中 から 1: 待機中 に変更する。
233//       *
234//       * @og.rev 7.2.5.3 (2020/06/16) 処理のスレッドを停止した時に、GF70.FGYKANを、3:実行中→1: 待機中 に更新する。
235//       */
236//      public static void stopFgykan() {
237//              // 更新用の値
238//              final String NOW  = StringUtil.getTimeFormat();
239//              final String PGID = "CMNDLine";
240//
241//              DBUtil.execute( STOP_FGYKAN,NOW,PGID ); // 3:実行中→1: 待機中 に更新
242//      }
243
244        /**
245         *コマンドリストクラスの文字列表現を返します。
246         *
247         * @return      コマンドリストクラスの文字列表現
248         */
249        @Override               // Object
250        public String toString() { return cmndStr ; }
251}