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}